Contents

Serverless function에 λŒ€ν•˜μ—¬

   Jun 26, 2023     1 min read

μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜μ— λŒ€ν•œ κΈ€μž…λ‹ˆλ‹€.

μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜(Serverless Functions)ν•¨μˆ˜λž€?

ν΄λΌμš°λ“œ μ»΄ν“¨νŒ… ν™˜κ²½μ—μ„œ μ‹€ν–‰λ˜λŠ” 독립적인 ν•¨μˆ˜μž…λ‹ˆλ‹€. μ„œλ²„λ¦¬μŠ€ μ•„ν‚€ν…μ²˜λŠ” κ°œλ°œμžκ°€ μ„œλ²„ 인프라λ₯Ό κ΄€λ¦¬ν•˜μ§€ μ•Šκ³ λ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€. μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜λŠ” ν•„μš”ν•  λ•Œλ§Œ 호좜되며, 인프라 λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ μžλ™ ν™•μž₯κ³Ό 관리λ₯Ό ν΄λΌμš°λ“œ μ œκ³΅μ—…μ²΄κ°€ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

λ˜ν•œ, 이벀트 기반(event-driven)으둜 λ™μž‘ν•˜λ©°, νŠΉμ • μ΄λ²€νŠΈκ°€ λ°œμƒν•˜λ©΄ μ‹€ν–‰λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, HTTP μš”μ²­, λ©”μ‹œμ§€ 큐, 타이머 λ“±μ˜ μ΄λ²€νŠΈκ°€ μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜λ₯Ό νŠΈλ¦¬κ±°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ν•¨μˆ˜λŠ” 단일 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ©°, 일반적으둜 λͺ‡ μ΄ˆμ—μ„œ λͺ‡ λΆ„κΉŒμ§€ 짧은 μ‹€ν–‰ μ‹œκ°„μ„ κ°–μŠ΅λ‹ˆλ‹€.

μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜μ˜ μ£Όμš” νŠΉμ§•
  • κ΄€λ¦¬μ˜ κ°„μ†Œν™”: μ„œλ²„ 인프라λ₯Ό 관리할 ν•„μš” 없이 κ°œλ°œμžλŠ” ν•¨μˆ˜μ˜ μ½”λ“œμ— 집쀑할 수 μžˆμŠ΅λ‹ˆλ‹€. 인프라 μžλ™ν™”, ν™•μž₯, λͺ¨λ‹ˆν„°λ§ 등은 ν΄λΌμš°λ“œ μ œκ³΅μ—…μ²΄κ°€ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

  • 이벀트 트리거: ν•¨μˆ˜λŠ” μ΄λ²€νŠΈμ— μ˜ν•΄ 트리거되며, ν•„μš”ν•œ 경우 μžλ™μœΌλ‘œ ν™•μž₯λ©λ‹ˆλ‹€. μ΄λ²€νŠΈλŠ” λ‹€μ–‘ν•œ μ†ŒμŠ€μ—μ„œ λ°œμƒν•  수 있으며, μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜λ₯Ό νŠΈλ¦¬κ±°ν•˜μ—¬ μ‹€ν–‰ν•©λ‹ˆλ‹€.

  • 과금 방식: λŒ€λΆ€λΆ„μ˜ μ„œλ²„λ¦¬μŠ€ ν”Œλž«νΌμ€ ν•¨μˆ˜μ˜ μ‹€ν–‰ μ‹œκ°„κ³Ό λ¦¬μ†ŒμŠ€ μ†ŒλΉ„λŸ‰μ— 따라 κ³ΌκΈˆν•©λ‹ˆλ‹€. ν•¨μˆ˜κ°€ λΉ„ν™œμ„± μƒνƒœμΈ κ²½μš°μ—λ„ 인프라 λ¦¬μ†ŒμŠ€κ°€ ν• λ‹Ήλ˜μ§€ μ•ŠμœΌλ―€λ‘œ 효율적인 λΉ„μš© 관리가 κ°€λŠ₯ν•©λ‹ˆλ‹€.

  • ν™•μž₯μ„±: ν•¨μˆ˜λŠ” ν•„μš”μ— 따라 μžλ™μœΌλ‘œ ν™•μž₯λ˜λ―€λ‘œ, νŠΈλž˜ν”½μ΄ μ¦κ°€ν•˜κ±°λ‚˜ λΆ€ν•˜κ°€ λ°œμƒν•  λ•Œλ„ μ•ˆμ •μ μœΌλ‘œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ„œλ²„λ¦¬μŠ€ ν•¨μˆ˜ μ˜ˆμ‹œ(Vercel)
const sharp = require("sharp");

module.exports = async (req, res) => {
  try {
    const { image } = req.body; // 이미지 λ°μ΄ν„°λŠ” μš”μ²­μ˜ λ°”λ””λ‘œλΆ€ν„° λ°›μ•„μ˜΅λ‹ˆλ‹€.

    // 이미지 압좕을 μœ„ν•΄ sharp 라이브러리λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
    const compressedImageBuffer = await sharp(image)
      .resize(800) // 이미지 리사이징
      .toBuffer(); // μ••μΆ•λœ 이미지 버퍼 λ°˜ν™˜

    // μ••μΆ•λœ 이미지λ₯Ό μ €μž₯ν•˜κ±°λ‚˜ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
    // 이 μ˜ˆμ‹œμ—μ„œλŠ” μ••μΆ•λœ 이미지λ₯Ό λ°”λ‘œ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ°˜ν™˜ν•©λ‹ˆλ‹€.
    res.setHeader("Content-Type", "image/jpeg");
    res.send(compressedImageBuffer);
  } catch (error) {
    console.error("Image compression error:", error);
    res.status(500).send("Image compression failed.");
  }
};
μ˜ˆμ‹œ μ„€λͺ…

sharp 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ 이미지 압좕을 μ²˜λ¦¬ν•©λ‹ˆλ‹€. μ• μ¦ˆνŽ‘μ…˜μ˜ μš”μ²­ λ°”λ””λ‘œλΆ€ν„° 이미지 데이터λ₯Ό λ°›μ•„μ˜¨ ν›„, sharpλ₯Ό μ‚¬μš©ν•˜μ—¬ 이미지λ₯Ό λ¦¬μ‚¬μ΄μ§•ν•˜κ³  μ••μΆ•λœ 이미지 버퍼λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. λ§ˆμ§€λ§‰μœΌλ‘œ, μ••μΆ•λœ 이미지λ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λ°˜ν™˜ν•©λ‹ˆλ‹€.