Serverless
서버리스
서버 관리 없이 코드 실행. Lambda, Cloud Functions. 사용량 과금.
서버리스
서버 관리 없이 코드 실행. Lambda, Cloud Functions. 사용량 과금.
서버리스(Serverless)는 서버 인프라 관리 없이 코드를 실행하는 클라우드 컴퓨팅 모델입니다. 개발자는 비즈니스 로직에만 집중하고, 서버 프로비저닝, 스케일링, 패치 등은 클라우드 제공자가 담당합니다. "서버가 없다"는 뜻이 아니라 "서버를 신경 쓰지 않아도 된다"는 의미입니다.
FaaS(Function as a Service)가 대표적인 서버리스 서비스입니다. AWS Lambda, Google Cloud Functions, Azure Functions가 있습니다. HTTP 요청, 파일 업로드, DB 변경 등 이벤트에 반응하여 함수가 실행됩니다. 실행된 시간(ms 단위)과 요청 수에 따라 과금되어, 트래픽이 없으면 비용이 거의 없습니다.
서버리스의 장점은 무한한 자동 스케일링, 운영 부담 제거, 사용량 기반 과금입니다. 갑작스런 트래픽 급증에도 자동으로 인스턴스가 늘어나고, 유휴 시간에는 비용이 발생하지 않습니다. MVP, 이벤트 기반 처리, 주기적 배치 작업에 매우 적합합니다.
단점은 콜드 스타트(Cold Start) 지연, 실행 시간 제한(AWS Lambda 15분), 상태 유지 어려움입니다. 첫 요청이나 오랜 유휴 후 요청에서 컨테이너 초기화 시간이 발생합니다. Provisioned Concurrency로 웜 상태 유지가 가능하지만 추가 비용이 발생합니다. 복잡한 장기 실행 작업에는 부적합할 수 있습니다.
// AWS Lambda 함수 (TypeScript)
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, PutCommand, GetCommand } from '@aws-sdk/lib-dynamodb';
const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);
// Lambda 핸들러 함수
export const handler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
try {
const { httpMethod, body, pathParameters } = event;
if (httpMethod === 'POST') {
// 사용자 생성
const userData = JSON.parse(body || '{}');
await docClient.send(new PutCommand({
TableName: process.env.USERS_TABLE!,
Item: {
userId: crypto.randomUUID(),
...userData,
createdAt: new Date().toISOString()
}
}));
return {
statusCode: 201,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'User created' })
};
}
if (httpMethod === 'GET') {
// 사용자 조회
const { userId } = pathParameters || {};
const result = await docClient.send(new GetCommand({
TableName: process.env.USERS_TABLE!,
Key: { userId }
}));
if (!result.Item) {
return {
statusCode: 404,
body: JSON.stringify({ error: 'User not found' })
};
}
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result.Item)
};
}
return {
statusCode: 405,
body: JSON.stringify({ error: 'Method not allowed' })
};
} catch (error) {
console.error('Error:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Internal server error' })
};
}
};
// serverless.yml (Serverless Framework)
/*
service: user-api
provider:
name: aws
runtime: nodejs20.x
region: ap-northeast-2
environment:
USERS_TABLE: ${self:service}-users-${sls:stage}
iam:
role:
statements:
- Effect: Allow
Action:
- dynamodb:PutItem
- dynamodb:GetItem
Resource: !GetAtt UsersTable.Arn
functions:
users:
handler: src/handlers/users.handler
events:
- httpApi:
path: /users
method: post
- httpApi:
path: /users/{userId}
method: get
# 콜드 스타트 방지 (추가 비용 발생)
# provisionedConcurrency: 2
resources:
Resources:
UsersTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.USERS_TABLE}
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
*/
스타트업 기술 결정에서:
"초기에 Lambda로 시작하면 인프라 비용 거의 없이 MVP 출시할 수 있어요. 트래픽 예측이 어려울 때도 자동 스케일링되니까 안심이고요. 나중에 트래픽 패턴이 안정되면 컨테이너로 마이그레이션 검토해도 됩니다."
기술 면접에서:
"Lambda 콜드 스타트 문제 어떻게 해결하나요?" - "여러 방법이 있어요. Provisioned Concurrency로 웜 상태 유지하거나, 번들 크기 최소화, Node.js나 Python 같은 가벼운 런타임 사용, SDK 지연 로딩 등이요. 또는 CloudWatch Events로 주기적 워밍도 가능합니다."
비용 최적화에서:
"Lambda 비용이 예상보다 높아요." - "실행 시간 분석해보세요. 메모리 설정 올리면 CPU도 비례해서 늘어나서 오히려 실행 시간이 줄어 비용이 낮아질 수 있어요. AWS Lambda Power Tuning으로 최적 메모리 찾아보세요."