Azure App Service vs Azure Functions 차이: 언제 무엇을 선택할까

2026. 6. 6. 17:36Cloud/Azure

반응형

App Service는 상시 실행되는 웹 애플리케이션을 위한 PaaS이고, Azure Functions는 이벤트에 반응하는 함수 단위 서버리스(FaaS)입니다. 둘 다 코드를 배포하면 인프라를 관리해주지만, 과금 모델과 스케일링 방식이 근본적으로 다릅니다. 워크로드 특성에 따라 비용 차이가 수배에서 수십 배까지 벌어질 수 있습니다.

핵심 요약

  • App Service는 App Service Plan(VM 인스턴스)을 할당받아 상시 실행됩니다. 트래픽이 없어도 인스턴스 비용이 발생합니다.
  • Azure Functions는 Consumption Plan에서 실행 횟수와 실행 시간 기준으로 과금됩니다. 트래픽이 없으면 비용이 0에 수렴합니다.
  • App Service는 여러 엔드포인트, 미들웨어, WebSocket, 백그라운드 작업을 하나의 서비스에서 처리합니다.
  • Azure Functions는 단일 이벤트에 단일 작업을 수행하는 구조에 최적화되어 있습니다.
  • Functions도 Premium Plan이나 Dedicated Plan(App Service Plan)에서 실행하면 상시 가동이 가능하지만, 이 경우 App Service와 비용 구조가 유사해집니다.

1. 왜 이 비교가 필요한가

Azure에 REST API를 하나 배포하려고 합니다. App Service에 올릴 수도 있고, Azure Functions로 만들 수도 있습니다. 둘 다 .NET, Node.js, Python, Java를 지원하고, 배포하면 HTTPS 엔드포인트가 생기며, Azure Monitor로 모니터링할 수 있습니다.

그런데 막상 선택하려면 혼란이 생깁니다.

  • "간단한 API인데 App Service Plan을 만들면 과한 거 아닌가?"
  • "Functions로 만들었는데 Cold Start 때문에 응답이 느린데, 이걸 감수해야 하나?"
  • "처음엔 Functions로 시작했는데 기능이 커지면 App Service로 옮겨야 하나?"

이 글에서는 두 서비스의 구조적 차이를 정리하고, 워크로드 특성에 따른 선택 기준을 제시합니다.

2. 서비스 개요

2.1 Azure App Service

App Service는 웹 애플리케이션, REST API, 모바일 백엔드를 호스팅하는 관리형 PaaS(Platform as a Service)입니다. 사용자는 코드나 컨테이너를 배포하고, 플랫폼이 OS 패치, 로드 밸런싱, 자동 스케일링을 처리합니다.

항목 설명
배포 단위 웹 애플리케이션 (코드 또는 컨테이너)
실행 모델 상시 실행 (App Service Plan 인스턴스 위에서 동작)
스케일링 수동 또는 자동 스케일링 (인스턴스 수 조정)
런타임 .NET, Node.js, Python, Java, PHP, Ruby, 커스텀 컨테이너
상태 Stateless 권장 (인스턴스 간 상태 공유 없음)

App Service의 핵심은 "VM을 직접 관리하지 않지만, 전용 인스턴스가 항상 실행된다" 는 것입니다. 웹 서버가 24시간 요청을 기다리며 실행 중이고, 요청이 없어도 인스턴스가 유지됩니다.

2.2 Azure Functions

Azure Functions는 이벤트 기반 서버리스 컴퓨팅 플랫폼입니다. 함수 단위로 코드를 배포하고, 이벤트가 발생할 때만 실행됩니다.

항목 설명
배포 단위 함수 (Function App 단위로 그룹화)
실행 모델 이벤트 트리거 시 함수 실행
스케일링 0에서 N까지 자동 스케일링 (이벤트 기반)
런타임 .NET, Node.js, Python, Java, PowerShell, 커스텀 핸들러
상태 Stateless (Durable Functions로 상태 관리 가능)

Azure Functions의 핵심은 "이벤트가 없으면 실행하지 않고, 있으면 즉시 스케일 아웃한다" 는 것입니다. Consumption Plan에서는 Scale to Zero가 기본이며, 100개 이상의 인스턴스로 순간적으로 확장할 수 있습니다.

호스팅 옵션의 유연성
Azure Functions는 Consumption Plan(서버리스) 외에도 Premium Plan, Dedicated Plan(App Service Plan), Container Apps 환경에서 실행할 수 있습니다. 호스팅 플랜에 따라 스케일링, Cold Start, 비용 특성이 크게 달라지므로, "Azure Functions = 서버리스"라고 단정하면 안 됩니다.

3. 아키텍처 비교

App Service vs Azure Functions 아키텍처 비교
App Service vs Azure Functions 아키텍처 비교

두 서비스의 실행 구조를 비교하면 다음과 같습니다.

App Service: 1. App Service Plan(SKU)을 선택합니다 (B1, S1, P1v3 등). 2. 선택한 SKU에 해당하는 VM 인스턴스가 할당됩니다. 3. 코드 또는 컨테이너를 배포합니다. 4. 인스턴스가 상시 실행되며, 들어오는 요청을 처리합니다. 5. 부하가 증가하면 인스턴스 수를 늘립니다 (수동 또는 자동 스케일링).

Azure Functions (Consumption Plan): 1. Function App을 생성합니다 (호스팅 플랜 선택). 2. 함수 코드를 배포합니다. 3. 이벤트(HTTP 요청, 큐 메시지, 타이머 등)가 발생하면 플랫폼이 인스턴스를 할당합니다. 4. 함수가 실행되고, 완료 후 인스턴스가 유휴 상태로 전환됩니다. 5. 일정 시간 유휴 상태가 지속되면 인스턴스가 해제됩니다 (Scale to Zero).

4. 주요 차이점 비교

4.1 실행 모델과 스케일링

App Service vs Azure Functions 스케일링 비교
App Service vs Azure Functions 스케일링 비교
기준 App Service Azure Functions (Consumption) Azure Functions (Premium)
실행 방식 상시 실행 이벤트 시에만 실행 상시 + 이벤트 기반 확장
Scale to Zero 불가 (최소 1 인스턴스) 지원 불가 (최소 1 인스턴스)
최대 인스턴스 SKU별 최대 30개 (Pv3: 30) 200개 100개
스케일 아웃 속도 수분 (VM 시작 시간) 수초~수십 초 사전 워밍된 인스턴스 즉시 할당
스케일 단위 인스턴스 (전체 앱) 인스턴스 (함수 앱 단위) 인스턴스 (함수 앱 단위)
자동 스케일 기준 CPU, 메모리, HTTP 큐 등 규칙 기반 이벤트 소스 백로그 이벤트 소스 백로그

실무 시나리오:

SaaS 웹 애플리케이션의 메인 API를 운영한다면, App Service가 적합합니다. 상시 요청을 처리해야 하고, Cold Start로 인한 첫 응답 지연을 허용할 수 없기 때문입니다.

반면 "주문이 접수되면 이메일을 발송한다"처럼 이벤트에 반응하는 비동기 작업은 Azure Functions가 적합합니다. 주문이 없으면 비용이 0이고, 블랙프라이데이에 주문이 폭증하면 자동으로 수백 인스턴스로 확장됩니다.

4.2 비용 구조

App Service vs Azure Functions 비용 구조 비교
App Service vs Azure Functions 비용 구조 비교
기준 App Service Azure Functions (Consumption) Azure Functions (Premium)
과금 단위 인스턴스 시간 (초 단위) 실행 횟수 + 실행 시간 인스턴스 시간 (초 단위)
최소 비용 Plan SKU 비용 (B1: ~$13/월) $0 (무료 티어 내) EP1: ~$155/월
무료 티어 F1 (제한적: 60분 CPU/일) 월 100만 실행 + 400,000 GB-초 없음
유휴 시 비용 발생 (인스턴스 유지) 미발생 (Scale to Zero) 발생 (최소 인스턴스 유지)
예측 가능성 높음 (고정 비용) 낮음 (사용량 비례) 높음 (기본 + 버스트)

비용 시나리오 비교:

하루 평균 10,000건의 API 호출을 처리하는 서비스를 가정합니다. 각 요청의 평균 실행 시간은 200ms, 메모리 사용량은 256MB입니다.

  • App Service (B1): ~$13/월 (고정). 트래픽 증감과 무관.
  • Azure Functions (Consumption): 월 30만 건 × 0.2초 × 0.25GB = 15,000 GB-초. 무료 티어(400,000 GB-초) 안에 포함. 실질 비용 ~$0.
  • Azure Functions (Consumption): 만약 하루 100만 건이면 월 3,000만 건. 무료 티어 초과분에 대해 ~$15~20/월.

간헐적 트래픽에는 Functions Consumption이 압도적으로 저렴합니다. 다만 트래픽이 상시 높은 수준으로 유지되면, App Service의 고정 비용이 오히려 예측 가능하고 경제적일 수 있습니다.

비용 함정: Premium Plan
Functions에서 Cold Start를 없애려고 Premium Plan(EP1)을 선택하면, 최소 비용이 App Service P1v3와 비슷한 수준(~$155/월)이 됩니다. "서버리스니까 저렴하겠지"라는 가정 없이, 실제 호스팅 플랜 기준으로 비용을 비교해야 합니다.

4.3 개발 경험과 배포

기준 App Service Azure Functions
프로젝트 구조 일반 웹 애플리케이션 프로젝트 Function App + 개별 함수 파일
라우팅 프레임워크 내장 라우터 (Express, ASP.NET 등) 함수별 바인딩(route) 또는 HTTP 트리거
미들웨어 프레임워크 미들웨어 체인 제한적 (함수 필터)
로컬 개발 일반 웹 서버 실행 Azure Functions Core Tools
배포 방식 ZIP Deploy, Git, Container, GitHub Actions ZIP Deploy, Git, VS Code 확장, GitHub Actions
스테이징 슬롯 지원 (Standard 이상) 지원 (Premium 이상)
WebSocket 지원 미지원 (SignalR Service 연동 필요)
백그라운드 작업 WebJobs 또는 애플리케이션 내 구현 타이머 트리거, 큐 트리거로 구현

실무 시나리오:

Express.js로 20개 엔드포인트가 있는 REST API를 운영합니다. 인증 미들웨어, 요청 검증, 에러 핸들링이 공통으로 적용됩니다. 이런 구조는 App Service에 올리는 것이 자연스럽습니다. 기존 코드를 그대로 배포할 수 있습니다.

반면 "Blob Storage에 파일이 업로드되면 바이러스 스캔을 실행한다"처럼 단일 트리거에 단일 작업을 수행하는 경우, Azure Functions의 바인딩 모델이 더 간결합니다. Blob 트리거를 선언하면 플랫폼이 파일 감지부터 함수 호출까지 처리합니다.

4.4 이벤트 트리거와 바인딩

트리거/바인딩 App Service Azure Functions
HTTP 요청 ✅ 기본 지원 ✅ HTTP 트리거
타이머 (CRON) WebJobs 또는 외부 스케줄러 ✅ Timer 트리거
Queue Storage WebJobs 또는 SDK 폴링 ✅ Queue 트리거
Service Bus SDK로 직접 구현 ✅ Service Bus 트리거
Blob Storage SDK로 직접 구현 ✅ Blob 트리거
Event Grid Webhook 엔드포인트 구현 ✅ Event Grid 트리거
Cosmos DB Change Feed SDK 직접 구현 ✅ Cosmos DB 트리거
Event Hub SDK로 직접 구현 ✅ Event Hub 트리거

Azure Functions의 핵심 강점은 트리거와 바인딩 시스템입니다. 입력(트리거)과 출력(바인딩)을 선언적으로 정의하면, SDK 연동 코드를 직접 작성할 필요가 없습니다.

// Azure Functions — Blob 트리거 + Queue 출력 바인딩
[Function("ProcessImage")]
[QueueOutput("thumbnails")]
public string Run(
    [BlobTrigger("uploads/{name}")] Stream image,
    string name)
{
    // 이미지 처리 로직만 작성
    return $"thumbnail-{name}";
}

같은 작업을 App Service에서 구현하려면, Blob Storage SDK로 Change Feed를 폴링하거나, Event Grid Webhook을 직접 처리하는 코드를 작성해야 합니다.

4.5 리소스 제한

기준 App Service Azure Functions (Consumption) Azure Functions (Premium)
실행 시간 제한 없음 (상시 실행) 최대 10분 (기본 5분) 무제한 (기본 30분)
메모리 SKU별 (B1: 1.75 GB ~ P3v3: 32 GB) 1.5 GB SKU별 (EP1: 3.5 GB ~ EP3: 14 GB)
디스크 SKU별 (10 GB ~ 1 TB) 제한적 (임시 저장소) SKU별
아웃바운드 연결 제한 없음 (인스턴스 리소스 범위) 인스턴스당 600 활성 연결 인스턴스당 제한 완화
VNet 통합 지원 (Standard 이상) 지원 (Premium 이상) 지원

Consumption Plan의 실행 시간 제한(최대 10분)은 긴 처리가 필요한 워크로드에서 치명적입니다. 대용량 파일 처리나 복잡한 워크플로우는 Durable Functions를 사용하거나, Premium Plan으로 전환하거나, App Service를 선택해야 합니다.

5. 선택 기준 의사결정

App Service vs Azure Functions 선택 의사결정 흐름
App Service vs Azure Functions 선택 의사결정 흐름

App Service를 선택하는 경우

  • 상시 실행되는 웹 애플리케이션 (포털, 대시보드, SaaS 서비스)
  • 여러 엔드포인트를 하나의 서비스로 관리해야 할 때
  • WebSocket이 필요한 실시간 통신 (채팅, 알림)
  • 미들웨어 체인이 복잡한 경우 (인증, 로깅, 요청 변환)
  • 예측 가능한 고정 비용이 필요한 경우
  • 응답 지연에 민감하여 Cold Start를 허용할 수 없는 경우 (Premium Plan 비용을 감당할 수 없다면)
  • 기존 웹 프레임워크 기반 애플리케이션을 마이그레이션할 때
  • 긴 실행 시간의 백그라운드 처리가 필요한 경우

Azure Functions를 선택하는 경우

  • 이벤트 기반 비동기 작업 (파일 업로드 처리, 큐 메시지 소비, DB 변경 감지)
  • 간헐적 트래픽: 하루 수천 건 이하의 호출
  • 비용 최소화가 최우선인 경우 (무료 티어 활용)
  • 스케줄 작업 (매시간 데이터 동기화, 일일 리포트 생성)
  • 급격한 트래픽 스파이크에 대응해야 하는 경우 (자동 스케일 아웃)
  • Azure 서비스 간 통합 글루 코드 (Service Bus → Cosmos DB, Blob → Queue)
  • 마이크로서비스의 개별 함수를 독립적으로 배포하고 싶을 때

판단이 어려운 경우

  • 트래픽이 일정 수준으로 상시 발생하면서 이벤트 트리거도 필요한 경우 → 혼합 구조 검토 (메인 API는 App Service, 이벤트 핸들러는 Functions)
  • Cold Start가 문제이지만 비용도 중요한 경우 → Functions Premium Plan의 최소 인스턴스 설정으로 절충
  • 서비스가 성장할 방향이 불확실한 경우 → Functions로 시작하고, 복잡도가 증가하면 App Service로 마이그레이션

6. 실무 아키텍처 예시

시나리오: B2B SaaS 플랫폼의 Azure 설계

기업용 문서 관리 SaaS를 Azure에 구축한다고 가정합니다.

컴포넌트 선택 이유
메인 웹 API (CRUD) App Service (S1) 20+ 엔드포인트, 인증 미들웨어, 상시 응답 필요
관리자 대시보드 App Service (동일 Plan) 같은 Plan에 슬롯 추가, WebSocket 알림
문서 업로드 후 처리 Azure Functions (Consumption) Blob 트리거, 간헐적, 처리 완료 후 큐에 결과 전달
PDF 변환 Azure Functions (Premium EP1) 변환에 5~30초 소요, Cold Start 허용 불가, 메모리 필요
일일 사용량 리포트 Azure Functions (Consumption) Timer 트리거, 하루 1회 실행, 비용 ~$0
알림 발송 Azure Functions (Consumption) Service Bus 트리거, 이메일/SMS 발송, 비동기
외부 시스템 연동 (Webhook) Azure Functions (Consumption) HTTP 트리거, 간헐적 호출, 단일 작업

이 구조에서 핵심 원칙:

  • 상시 실행 HTTP 서비스: App Service (예측 가능한 비용, 안정적 응답)
  • 이벤트 반응 단일 작업: Functions Consumption (비용 0에 수렴)
  • 이벤트 반응 + 성능 요구: Functions Premium (Cold Start 제거, 비용 증가 감수)

7. 운영 고려사항

모니터링과 진단

항목 App Service Azure Functions
Application Insights 자동 연동 자동 연동
로그 스트리밍 지원 지원
메트릭 응답 시간, HTTP 에러율, CPU/메모리 실행 횟수, 실행 시간, 에러율, 큐 길이
분산 트레이싱 Application Insights로 연동 Application Insights로 연동
스테이징 슬롯 Standard 이상 Premium 이상
디버깅 원격 디버깅, Kudu 콘솔 원격 디버깅, Kudu 콘솔

Functions에서 추가로 모니터링해야 할 항목:

  • 실행 실패율과 재시도: 큐 트리거는 실패 시 자동 재시도하므로, 독 메시지(poison message)가 누적될 수 있습니다.
  • Cold Start 빈도: Consumption Plan에서 Cold Start가 빈번하면 사용자 경험에 영향을 줍니다.
  • 호스트 상태: Function App 호스트가 비정상이면 모든 함수가 영향을 받습니다.

보안

항목 App Service Azure Functions
인증/인가 Easy Auth (내장) + 코드 레벨 구현 Easy Auth (내장) + 함수 키 + 코드 레벨
VNet 통합 지원 (Standard 이상) 지원 (Premium 이상)
Private Endpoint 지원 지원 (Premium 이상)
Managed Identity 지원 지원
IP 제한 지원 지원
커스텀 도메인 + TLS 지원 지원 (Premium 이상에서 원활)

보안 관점에서 주요 차이는 VNet 통합입니다. Functions Consumption Plan에서는 VNet 통합이 제한적이므로, Private Endpoint로 보호된 리소스(Azure SQL, Storage Account 등)에 접근하려면 Premium Plan이 필요합니다. 이 요구사항 하나로 Consumption Plan을 포기해야 하는 경우가 실무에서 빈번합니다.

Cold Start

항목 App Service Functions (Consumption) Functions (Premium)
Cold Start 발생 없음 (상시 실행) 있음 (수초~수십 초) 최소화 (사전 워밍)
영향 없음 첫 요청 응답 지연 버스트 시 일부 발생 가능
완화 방법 해당 없음 Premium 전환, 주기적 ping 최소 인스턴스 수 설정

Cold Start는 언어 런타임에 따라 차이가 큽니다. .NET과 Java는 Cold Start가 길고(수초~10초 이상), Node.js와 Python은 상대적으로 짧습니다(1~3초). 사용자 대면 HTTP API를 Consumption Plan에서 운영하면 UX 문제가 발생할 수 있습니다.

8. 마이그레이션 경로

Functions → App Service

서비스가 성장하면서 다음 요구가 생기면 App Service로의 전환을 검토합니다:

  • 함수 수가 20개 이상으로 늘어나 하나의 API로 통합이 필요한 경우
  • 미들웨어, 인증, 로깅을 공통으로 적용하고 싶은 경우
  • WebSocket이나 gRPC가 필요한 경우
  • Cold Start를 완전히 제거하고 싶지만 Premium Plan 비용이 부담인 경우

App Service → Functions

반대 방향의 전환은 드물지만, 다음 상황에서 검토할 수 있습니다:

  • 비용 절감이 최우선이고, 트래픽이 매우 간헐적인 경우
  • 모놀리식 서비스를 이벤트 기반 마이크로서비스로 분리하는 경우
  • 특정 기능만 분리하여 독립적으로 스케일링하고 싶은 경우

9. 요약 비교 테이블

기준 App Service Azure Functions (Consumption) Azure Functions (Premium)
실행 모델 상시 실행 (PaaS) 이벤트 시에만 (FaaS) 상시 + 이벤트 확장
과금 인스턴스 시간 (고정) 실행 횟수 + 시간 (종량) 인스턴스 시간 (고정)
Scale to Zero 불가 지원 불가
Cold Start 없음 있음 (수초~수십 초) 최소화
최대 스케일 아웃 30 인스턴스 200 인스턴스 100 인스턴스
VNet 통합 Standard 이상 제한적 지원
실행 시간 제한 없음 최대 10분 무제한
이벤트 트리거 수동 구현 네이티브 바인딩 네이티브 바인딩
적합한 워크로드 웹 앱, REST API, 실시간 서비스 이벤트 핸들러, 스케줄 작업, 글루 코드 이벤트 핸들러 + 성능 요구

10. 결론

App Service와 Azure Functions는 "웹 서비스" vs "이벤트 핸들러"라는 다른 설계 의도를 가지고 있습니다. 같은 HTTP API를 양쪽 모두에서 구현할 수 있지만, 선택의 핵심은 과금 모델과 실행 특성이 워크로드에 맞는가입니다.

선택 기준을 한 줄로 요약하면:

  • 상시 실행되는 웹 서비스, 예측 가능한 트래픽, 복잡한 라우팅 → App Service
  • 이벤트 반응, 간헐적 실행, 비용 최소화, 급격한 스케일 아웃 → Azure Functions (Consumption)
  • 이벤트 반응 + Cold Start 제거 + VNet 접근 → Azure Functions (Premium)

실무에서는 하나의 아키텍처 안에서 두 서비스를 함께 사용하는 것이 일반적입니다. 메인 API는 App Service로, 비동기 이벤트 처리는 Functions로 구성하면 각 서비스의 강점을 활용하면서 비용도 최적화할 수 있습니다.


참고 자료

반응형