AWS Lambda Web Functions

AWS Lambda Web Functions

aws.amazon.com ▲ 103 댓글 95 HatchedLake721

요약

AWS가 평범한 웹 서버 코드를 고치지 않고 그대로 돌리는 AWS Lambda Web Functions를 내놓았습니다.

AWS 뉴스 블로그가 10월 12일 발표한 새 Lambda 실행 방식입니다. 지금까지 Lambda에 올리려면 이벤트를 하나씩 받는 핸들러 형태로 코드를 다시 짜야 했습니다. 이번에는 Express, Hono, Fastify, Next.js로 만든 서버를 그대로 배포할 수 있습니다.

왜 중요한가

  • 포트를 열어 요청을 받는 일반 웹 앱을 어댑터 없이 올릴 수 있어, Lambda 전용으로 코드를 고치던 부담이 사라집니다.
  • 과금 기준이 실행 시간 전체에서 실제 CPU 사용 시간으로 바뀝니다. 데이터베이스나 외부 API를 오래 기다리는 앱은 비용이 줄 수 있습니다.
  • Lambda가 이벤트 함수, 웹 함수, 마이크로VM(격리된 경량 가상 머신) 세 형태로 나뉘어, 용도에 맞춰 고르는 서비스가 됩니다.

핵심 내용

  • 실행 환경 하나가 요청을 최대 128개까지 동시에 처리해, 몰리는 요청을 이미 켜진 환경에서 나눠 받습니다.
  • CPU는 실제로 쓴 시간만큼, 메모리는 실행 환경이 살아 있는 동안 요금을 매깁니다.
  • 여러 리전에 복제하면 전역 주소 하나로 지연이 가장 짧은 리전에 자동으로 연결됩니다.
  • 명령 하나로 1분 안에 배포와 HTTPS 주소 발급을 끝내고, 리비전별로 트래픽을 나눠 카나리 배포(새 버전을 일부 요청에만 먼저 내보내는 방식)도 할 수 있습니다.
  • 출시 시점에는 Node.js 24(Arm64)만 지원하며, 미국 3곳과 도쿄, 아일랜드 등 5개 리전에서 쓸 수 있습니다.

HN 반응

  • Cloudflare Workers의 성공에 대한 대응이라는 해석과 함께, 기존 라이브러리로 비슷한 구성을 이미 써 왔다는 경험담이 나왔습니다.
  • 일부 이용자는 서버리스 함수가 배포·로깅·모니터링을 더 어렵게 만든다고 비판했고, 드물거나 갑자기 몰리는 트래픽에는 싸고 확장이 빠르다는 반박이 맞섰습니다.

댓글

30개 표시 · 전체 95개
  1. julianwood HN

    실제로 어떻게 동작하는지 정리해 봤습니다: https://aws.amazon.com/blogs/compute/exploring-aws-lambda-web-functions-for-building-web-appli 직접 써 볼 수 있는 코드 샘플도 모아 두었습니다: https://serverlessland.com/patterns?services=lambda-web-functions

  2. cogythea HN

    그런데 그 블로그 링크는 404가 뜨네요.

  3. Shakahs HN
  4. tkcranny HN

    꽤 흥미로워 보이네요. 클라우드플레어 워커스를 비롯한 호스팅 플랫폼들이 급성장한 게, 웹 앱을 더 "평범한" 모양으로 돌릴 수 있게 한 람다 신기능이 나오게 된 계기였을 거라고 봅니다.

  5. Lucasoato HN

    저도 클라우드플레어 워커스의 성공에 대한 대응이라는 인상을 받았어요. 근데 AWS Lambda 웹 함수는 컨테이너에서 돌아가나요, 아니면 WASM인가요?

  6. chrismustcode HN

    마이크로VM이고, 파이어크래커일 거라고 짐작합니다.

  7. squiwardStan5 HN

    표준 파이어크래커 마이크로VM이라고 알고 있습니다.

  8. julianwood HN

    네, 맞습니다. 격리를 위해 하드웨어 가상화를 씁니다.

  9. nemothekid HN

    Rust + Axum은 미들웨어( https://github.com/lazear/axum-aws-lambda )로 이미 어느 정도 이걸 지원해 왔습니다. 기본적으로 API를 평소처럼 작성하고, 람다용으로 빌드할 때 기능 플래그 하나만 켜면 특수 핸들러를 알아서 붙여 줍니다.

    여기에 Function URL과 CloudFront를 더하면 API 전체를 람다에서 호스팅하게 됩니다. 저는 이런 식으로 호스팅하는 백엔드가 있는데, 기본적인 인증이나 데이터베이스 연결은 물론이고 이미지·동영상 업로드와 이미지 변환까지 꽤 복잡한 일을 합니다. HTMX/Alpine으로 프런트엔드 렌더링도 하고요.

    봇 트래픽까지 다 받으면서 한 달 요청이 1,500만 건에 가까운데도 비용은 월 10달러 미만입니다(지연 시간 중앙값은 대략 90ms). Rust 런타임에서는 콜드 스타트가 문제가 되지 않습니다.

  10. remify HN

    저는 람다를 백엔드로 쓰는 애플리케이션을 두 개 만들었는데, 얼마나 단순한지 정말 마음에 듭니다. 람다 부분은 말 그대로 0달러가 듭니다.

    프런트엔드는 CloudFront에 올리고 백엔드는 람다로 돌리니, 사실상 데이터베이스와 인증서 비용만 냅니다.

    서버는 물론 도커 이미지도 관리하고 싶지 않습니다. 그냥 제 코드가 거기에 있기만 하면 되니까, 이런 방식이 좋습니다.

  11. holler HN

    서버는 물론 도커 이미지도 관리하고 싶지 않습니다. 그냥 제 코드가 거기에 있기만 하면 되니까, 이런 방식이 좋습니다.

    동의합니다. 다만 현실에서는 API를 컨테이너로 만들어 k8s 뒤에 두는 경우가 더 흔해서 아쉽습니다.

  12. torginus HN

    이와 아주 비슷한 건 Node용 serverless-express로 이미 가능했습니다:

    https://github.com/CodeGenieApp/serverless-express

    람다의 'handler' 함수를 감싸서 그 위에서 express를 돌리는 방식입니다. 요청 사이에 아무것도 유지되지 않는 Node 웹 서버를 얻는 셈이라 보통은 믿고 기대기 좋은 구조는 아니지만, 지속 TCP 연결을 쓰면 어느 정도 상태 유지도 흉내 낼 수 있습니다.

    물론 진짜 HTTP가 아니라서 WebSocket 같은 건 쓸 수 없지만, CRUD 백엔드 한두 개 만들기에는 충분합니다.

    다른 런타임에도 비슷한 라이브러리가 있습니다.

  13. bob1029 HN

    클라이언트 엣지 컴퓨팅처럼 다른 방법으로는 도저히 풀 수 없는 요구 사항이 정말로 있는 게 아니라면, 서비스형 함수(FaaS)는 절대 쓰지 말라고 강력히 권합니다.

    이 방식에서는 소프트웨어를 운영하는 모든 일이 더 어려워집니다. 인프라의 일부는 쉬워질 거라고 생각하기 쉽지만, 실제로는 같은 문제의 의미만 바뀔 뿐입니다. 치워야 할 난장판의 양은 그대로인데, 이제는 접근하기도 훨씬 어려운 이상한 더미들로 쌓여 있게 됩니다.

    환경당 최대 128개의 동시 요청

    t3a.nano 인스턴스 하나로도 그보다 더 많은 용량을 감당할 수 있다고 꽤 자신합니다.

  14. badatnames HN

    람다 얘기가 나올 때마다 이런 일방적인 주장이 꼭 올라오네요. 람다는 연산이나 RAM 요구량이 들쭉날쭉한 곳이라면 거의 어디서나 유용하고 쉽게 더 저렴합니다. 트랜스코딩 같은 무거운 작업도 마찬가지고요. 반면 t3.nano는 (아무것도 안 하는 작업에 3.50달러라) 값이 과하면서 동시에 (지속 네트워크 속도가 30Mbit/s라) 병목이 되기도 합니다. 람다를 잘못 쓸 수 있는 곳만큼이나 많은 곳에서요.

  15. ryandvm HN

    트래픽이 극단적으로 몰리는 부하에도 좋습니다. 저는 안드로이드 날씨 레이더 라이브 배경화면에 이미지를 보내 주는 레이더 영상 API에 람다를 폭넓게 쓰고 있습니다.

    이 용도는 트래픽이 거의 없다가도 허리케인 같은 상황이 오면 말 그대로 허리케인급 트래픽이 몰립니다.

    처리 부하가 일정하다면 전용 EC2 인스턴스로 돌리는 게 비용을 아낄 수 있을 것 같지만, 람다의 즉각적인 확장성은 따라올 수가 없어요.

    염치없는 홍보입니다: https://play.google.com/store/apps/details?id=app.radarlove.wallpaper

  16. CharlieDigital HN

    람다의 확장 방식에 딱히 특별한 건 없습니다. GCP Cloud Run[0]이나 Azure Container Apps[1]로도 똑같이 할 수 있어요.

    허용할 최대 인스턴스 수와 인스턴스당 최대 동시성을 지정하면 됩니다. 원하면 더 세밀한 확장 규칙도 설정할 수 있고요. 그러면 필요에 따라 0에서 n까지 알아서 확장합니다.

    [0] https://docs.cloud.google.com/run/docs/about-instance-autoscaling

    [1] https://learn.microsoft.com/en-us/azure/container-apps/scale-app?pivots=azure-cli

  17. badatnames HN

    확장 시간이 두 자릿수 배 이상 차이 나는 걸 딱히 특별하다고 안 치신다면야 그렇겠죠..

  18. CharlieDigital HN

    그렇게 돌아가는 게 아닙니다. 인스턴스 하나가 요청을 여러 개(인스턴스당 최대 1000개까지) 처리할 수 있으니까요. 그래서 예를 들어 부하가 75%일 때 확장되도록 설정하면 됩니다.

    인스턴스를 단일 스레드 핸들러로 구성했다면 당연히 고생하겠죠.

  19. badatnames HN

    그건 평균(mean())으로 애플리케이션 성능을 설명하는 잘못된 방식을 쓸 때나 통하는 얘기예요. 말씀하신 시나리오에서는 모든 요청이 과부하 상태인 인스턴스에 부딪히거나, 인스턴스가 줄어든 상태라면 기동까지 20~30초를 기다려야 합니다. 요청이 대화형이 아니기를, 짧은 타임아웃이 걸린 작업도 아니기를 빌어야 하죠. 두 메커니즘은 완전히 달라서 의미 있게 비교하기조차 어렵습니다.

  20. CharlieDigital HN
        > 말씀하신 시나리오에서는 모든 요청이 과부하 상태인 인스턴스에 부딪히거나,
    

    왜 그렇다는 건가요? Cloud Run 컨테이너와 .NET, Java, Go, Rust 같은 앱 런타임은 원래부터 멀티스레드, 멀티커넥션이 가능합니다. (크기만 충분하다면) 스레드와 async만으로 컨테이너당 최대 1000개의 동시 연결을 처리할 수 있어요. DB나 백엔드 서비스(S3 등)에 접근하는 작업은 어차피 I/O 바운드라서 대부분의 시간을 future에서 대기하며 보냅니다.

    컨테이너 인스턴스는 기본적으로 설정한 n까지(0 - n) 자동 확장되고, 확장 시점을 직접 정할 수도 있습니다. 트래픽이 한꺼번에 몰리는 게 걱정이라면, 용량 50%에서 확장되게 해서 애플리케이션에 여유가 있는 동안에도 준비된 인스턴스가 하나 있도록 하면 됩니다.

    이게 무너지는 경우는 DDoS인데, 그런 경우라면 저는 1) 그런 트래픽 급증을 다 받아내느니 차라리 무너지는 편이 어떤 경우든 낫고, 2) 그런 트래픽은 어차피 API Gateway + WAF에서 앞단에 걸러 내는 게 낫다고 봅니다.

    저는 용도에 따라 두 방식을 다 써 봤습니다(Azure Serverless Conf에 초청 발표자로 선 적도 있습니다). 그런데 요즘 제 생각은 서버리스 컨테이너가 거의 항상 더 낫다는 쪽입니다. 훨씬 유연하거든요.

    [0] https://learn.microsoft.com/en-us/shows/azure-serverless-conf/surfacing-fda-covid-data-using-serverless-functions-and-cosmosdb-with-charles-chen

  21. badatnames HN

    용량 50%에서 확장되게 하면 됩니다

    그러면 콜드 스타트 지연을 피하려고 돈을 두 배로 내는 셈인데, 애초에 우리가 얘기하던 게 바로 그 문제였잖아요.

  22. CharlieDigital HN

    Cloud Run은 유휴 상태에서는 과금하지 않습니다. 활성 상태일 때만 과금해요.

    그러니 용량 50%에서 유휴 시간이 많다면 0으로 줄어들 수 있습니다.

    0으로 줄어든다고 해서 "콜드"라는 뜻은 아닙니다. Cloud Run과 Container Apps를 "웜" 상태로 유지하면서 비용 면에서는 사실상 0으로 확장된 상태로 두는 쉬운 방법은, Cloud Scheduler를 크론으로 설정해 몇 분마다 헬스 엔드포인트를 핑하는 겁니다.

  23. rahimnathwani HN

    Cloud Run을 0으로 줄여 놓았다가 요청을 보내면, 그 즉시 깨어나서 최소 15분 뒤에 꺼질 때까지 요금이 부과되지 않나요?

  24. CharlieDigital HN

    0으로 줄어든 상태에서는 요청을 처리하는 동안에만 과금됩니다. 하지만 인스턴스가 바로 콜드 상태가 되지는 않습니다. 인스턴스가 활성 상태여도 요청을 처리하는 동안만 과금됩니다.

    이 도표를 보면 이해하기 쉽습니다: https://www.gstatic.com/bricks/image/5eb3c8e9-6159-4e2f-ba98-0ddd7d65d5f8.svg (맨 위의 회색 막대는 인스턴스가 시작되고 끝나는 시점이고, 파란 막대는 실제 요청, 초록 막대는 과금되는 구간입니다)

    요청 사이에 10초 간격이 있어도 그 10초는 과금되지 않지만, 사실상 여전히 뜨거운 상태입니다. 인스턴스는 멈추지 않아요. 10초 뒤에 다시 들어온 요청은 인스턴스가 아직 떠 있으니 시작 지연을 겪지 않습니다.

    이걸 활용해 콜드 스타트 없는 고처리량 시스템을 만들려면 어떻게 해야 할까요? 인스턴스가 멈추기 전에 짧은 요청(예: /health) 하나로 미리 데워 두면 됩니다.

  25. rahimnathwani HN

    저는 인스턴스 기반 과금(제가 늘 써 온 방식)을 말씀하시는 줄 알았는데, 요청 기반 과금을 말씀하시는 거였군요?

  26. CharlieDigital HN

    네, 요청 기반 과금이 맞습니다.

  27. greatgib HN

    버스트 부하에 좋다는 주장을 자주 듣는데, 실제로는 불편한 제약이 많습니다. 예를 들어 아주 비싼 프로비저닝을 돈 내고 쓰지 않는 한 동시 인스턴스 수나 확장 방식을 제대로 제어할 수 없습니다.

    그래서 새 람다 인스턴스가 떠서 요청에 응답하기까지 10초 이상 기다려야 할 수도 있습니다. 함수도 15분 안에 끝나야 하고, 람다가 따르는 이상한 동시성·확장 규칙도 감수해야 합니다.

  28. joshstrange HN

    동의하는 부분도 있고 아닌 부분도 있습니다. 저는 "1년 중 10달은 트래픽이 전혀 없고, 1~1.5달은 소량, 1주일 미만은 중간 정도, 하루나 이틀은 폭증"이라고 할 만큼 부하가 극단적으로 몰리는 소프트웨어 플랫폼을 여러 개 운영합니다(소프트웨어 이벤트가 아니라 오프라인에서 직접 열리는 행사 기반이에요). 람다가 까다롭다는 데 동의하고 람다에서 벗어나고 싶은 이유도 몇 가지 있지만, 과금 측면에서는 제 사용 사례에 거의 완벽하게 맞습니다. t3a.nano조차 비용이 더 들었을 테고, 제게 필요한 만큼 쉽게 확장되지도 않았을 겁니다.

    그래도 람다를 택한 걸 후회하는 순간이 있고, 비용이 더 들더라도 그냥 EC2 호스트를 쓰고 싶을 때가 있습니다. 배포가 더 쉽고 간단할 테니까요. 배포 과정을 개선하고 배포 시간을 줄이는 데 상당한 시간을 들였지만, 태그를 달고 나서 배포되기까지 여전히 2~3분이 걸립니다. VM이라면 더 빠르게 할 수 있다는 걸 압니다. 또 람다에서는 패키지, 바이너리, 로깅, 모니터링 등 모든 게 더 어려워집니다.

  29. vermilingua HN

    저는 정반대의 경험을 한 것 같습니다. 람다(다른 FaaS 플랫폼은 잘 모르겠지만)는 제게 너무 간단해서, 제 프로젝트에서 코드나 컨테이너를 따로 호스팅하려면 확실한 근거가 있어야 할 정도입니다.

    빠져 있는 비법은 IaC가 아닐까 싶습니다. 람다를 쉽게 쓰려면 어떤 IaC 솔루션이든 제대로 도입해야 하지만, 매끄럽게 만드는 데 그리 많은 양이 필요하지는 않습니다.

    비용과 연산 면에서는 FaaS가 분명히 엄격하게 더 나쁘지만, 대부분의 웹 워크로드는 굳이 최적일 필요가 없습니다.

  30. CharlieDigital HN

    Azure Container Apps나 GCP Cloud Run을 써 보지 않으셨다면, 선호하는 언어로 만든 표준 웹 API 앱을 배포해 보면서 견문을 넓힐 겸 한 번쯤 꼭 써 보시길 강력히 권합니다.

    어댑터가 필요 없습니다. 웹 API만 작성해서 올리면 됩니다. 공개 URL이 할당되고 바로 쓸 수 있어요. 코드는 특별한 어댑터나 에뮬레이터, 도구 없이 로컬에서도 그대로 돌아갑니다. 내일 다른 클라우드 플랫폼을 지원해야 하나요? 같은 컨테이너를 올리면 됩니다. 직접 관리하는 K8s로 옮기나요? 같은 컨테이너입니다.

Hacker News에서 보기 ↗