서버리스

Serverless

개념

서버를 직접 빌려 관리하지 않고 함수 단위로 코드를 올려 두었다가 요청이 올 때만 실행하는 방식입니다.

등장 배경

요청이 없는 시간에도 서버는 켜져 있고 그 시간에도 돈이 나갑니다. 하루에 200번 호출되는 내보내기 기능을 위해 한 대를 24시간 켜 두면, 실제로 코드가 도는 시간은 하루에 6분입니다. 나머지 23시간 54분은 아무 일도 하지 않으면서 같은 요금을 냅니다.

용량을 잡는 방식도 낭비를 키웠습니다. 몰리는 시각을 견딜 만큼 잡아 둬야 하니 월요일 오전 9시를 기준으로 서버를 준비하고, 그 기준으로 준비한 여력이 나머지 시간에는 대부분 놀고 있습니다.

켜 두는 일 자체에 붙는 업무도 있었습니다. 운영체제 보안 패치를 올리고, 디스크가 차기 전에 지우고, 새벽에 프로세스가 죽으면 다시 띄웁니다. 기능을 만드는 일과 상관없는데 누군가는 해야 하는 일들입니다. 새 기능을 하나도 더 만들지 않으면서 사람 한 명의 시간을 꾸준히 먹습니다.

그래서 실행 단위를 프로그램에서 함수로 낮추고, 아무 호출이 없는 동안에는 켜 둔 것이 없게 만드는 방식이 나왔습니다. 서버가 사라진 것이 아니라 서버를 신경 쓰는 사람이 우리에서 남으로 옮겨 간 것입니다.

작동 방식

함수 하나가 배포 단위이고 사건이 그것을 깨웁니다.

  1. 코드를 함수 단위로 올립니다. 요청 하나를 처리하는 코드, 파일이 올라왔을 때 변환하는 코드, 매일 새벽 3시에 집계하는 코드가 각각 따로 올라갑니다.
  2. 실행 환경은 필요할 때 만들어지고 한동안 호출이 없으면 사라집니다. 그래서 오랜만에 들어온 첫 요청은 환경을 준비하는 시간을 기다립니다. 이 지연을 콜드 스타트라고 하고, 언어와 준비할 것의 양에 따라 수백 밀리초에서 몇 초까지 걸립니다.
  3. 요금은 호출 수와 실행 시간에 붙습니다. 실행 시간은 쓴 메모리와 함께 곱해 셉니다. 하루에 6분 도는 기능이라면 6분만 값을 냅니다.
  4. 동시 실행은 알아서 늘어납니다. 같은 순간에 요청 500건이 들어오면 인스턴스 500개가 함께 돕니다. 여기서 문제가 자주 생기는데, 뒤에 있는 데이터베이스가 연결 500개를 감당하지 못하면 앞단이 늘어난 만큼 뒤가 막힙니다. 그래서 동시 실행 상한을 직접 걸어 두는 일이 실무의 절반입니다. 상한을 50으로 걸면 나머지 요청은 줄을 서고, 그 줄이 응답 시간으로 나타납니다.
  5. 상태를 들고 있을 수 없습니다. 함수 호출 사이에 기억이 남지 않고, 임시로 쓴 파일도 환경이 사라질 때 함께 사라집니다. 기억할 것은 전부 밖의 저장소에 둡니다.
  6. 실행 시간에 상한이 있습니다. 대개 몇 분이라 40초짜리 내보내기는 되지만 40분짜리 집계는 쪼개거나 다른 방식으로 옮겨야 합니다.

배포 단위가 작다는 점이 나중에 부담으로 돌아옵니다. 함수가 여든 개로 늘면 어느 사건이 무엇을 깨우는지가 코드만 읽어서는 보이지 않습니다. 그래서 목록과 호출 관계를 따로 문서로 두거나, 관련된 함수를 한 묶음으로 묶어 관리합니다.

쓰이는 곳

이 방식이 값을 하는 자리는 넷입니다.

  1. 간헐적이고 사건에 반응하는 일입니다. 파일이 올라왔을 때 미리보기를 만들고, 외부 서비스가 보내는 알림을 받아 처리하고, 정해진 시각에 집계하는 일이 여기 들어갑니다. 이 일들의 공통점은 사용자가 화면 앞에서 결과를 기다리고 있지 않다는 것입니다.
  2. 트래픽이 크게 튀는 일입니다. 마케팅 메일을 보낸 직후 10분 동안만 평소의 쉰 배가 들어오는 경우, 그 10분을 위해 서버를 늘려 두는 대신 알아서 늘어나게 둡니다.
  3. 두 서비스를 잇는 짧은 코드입니다. 결제 대행사가 보내는 신호를 받아 우리 형식으로 바꿔 넣는 정도의 일은 서버 한 대를 걸 만한 크기가 아닙니다.
  4. 새 기능을 시험해 보는 자리입니다. 서버를 준비하는 단계가 없으니 하루 안에 붙여 반응을 보고 접을 수 있습니다.

맞지 않는 자리도 분명합니다. 응답 지연에 민감하고 하루 종일 꾸준히 요청이 들어오는 기능은 계속 켜 두는 쪽이 싸고 빠릅니다. 몇십 분 도는 작업, 그리고 데이터베이스 연결 수가 빡빡한 구조도 이 방식과 부딪힙니다.

전부를 이 방식으로 만드는 팀은 드뭅니다. 대개 모놀리스 하나를 중심에 두고 사건에 반응하는 주변부만 함수로 떼어 놓습니다. 마이크로서비스처럼 기능별로 나누는 것과는 기준이 다릅니다. 나누는 기준이 기능이 아니라 실행 빈도와 사건이기 때문입니다.

실무 용례

"이건 하루에 200번 도는 기능이라 서버 켜 둘 필요 없습니다."

호출 빈도를 근거로 실행 방식을 고르는 말입니다.

"함수는 500개가 떴는데 데이터베이스가 못 버팁니다. 동시 실행 막아 주세요."

앞단만 늘어나면 뒤가 막힌다는 지적입니다.

"첫 호출이 3초 걸립니다. 이 화면에는 쓰면 안 됩니다."

콜드 스타트가 사용자에게 보이는 자리라는 판단입니다.

페이지덱이 문서 내보내기를 이 방식으로 옮겼습니다. 태오가 호출 기록을 보니 하루 200건이고 평일 오전에 몰렸습니다. 서버 한 대에 월 8만 원을 쓰던 기능이 함수로 옮긴 뒤 월 4,000원이 됐습니다.

같은 방식을 문서 열람에도 적용해 보자는 이야기가 나왔다가 접혔습니다. 열람은 하루 종일 끊이지 않고 들어오고 화면이 뜨는 속도에 바로 걸리는 기능이어서, 계산해 보니 요금도 더 나왔습니다. 두 기능의 차이는 크기가 아니라 호출이 고르게 들어오는지였습니다.

흔한 오해

서버가 없다는 말로 읽는 경우가 가장 많습니다. 이름이 그렇게 되어 있으니 자연스러운 오해입니다. 하지만 코드는 여전히 누군가의 서버에서 돕니다. 달라진 것은 그 서버를 준비하고 지키는 일을 우리가 하지 않는다는 점입니다. 없다고 읽으면 서버에서 나던 문제가 사라진다고 기대하게 되는데, 실행 시간 상한이나 동시 실행 한도처럼 이 방식에만 있는 제약이 그 자리를 대신합니다. 제약의 목록이 바뀐 것이고 제약이 없어진 것은 아닙니다.

항상 싸다고 보는 것도 흔합니다. 놀고 있는 시간에 돈을 내지 않으니 그렇게 보입니다. 하지만 호출이 꾸준히 많아지면 어느 지점에서 계속 켜 두는 쪽이 싸집니다. 하루 200건은 함수가 싸고 초당 200건은 서버가 싸며, 그 사이에 손익이 뒤집히는 지점이 있습니다. 옮기기 전에 지금 호출 수와 실행 시간으로 양쪽 요금을 계산해 보는 편이 낫습니다.

같이 보면 좋은 페이지

연관 용어

마지막 업데이트 2026-09-16