이벤트 로그 서버 구축 (2) - 데이터 수집 파트 1
1. 데이터 수집 파트
데이터 수집 파트는 이벤트 로그 서버에서 클라이언트가 전송하는 데이터를 수집하고, 이를 처리하여 적재 파트로 전달하는 역할을 수행합니다. 이 파트는 파라미터의 검증, 전처리, 전달 등을 담당합니다.
2. 사용할 AWS 서비스
AWS API Gateway
API Gateway는 AWS에서 제공하는 완전 관리형 서비스로, RESTful API를 생성, 배포, 관리할 수 있도록 지원합니다. 클라이언트와 백엔드 서비스 간의 통신을 중개하며, 인증/인가, 요청 검증, 속도 제한 등의 다양한 기능을 제공합니다. 이 프로젝트에서는 API Gateway를 활용해 이벤트 데이터를 수집하기 위한 엔드포인트를 제공하고, 요청을 Lambda로 전달합니다.
AWS Lambda
Lambda는 AWS의 서버리스 컴퓨팅 서비스로, 서버를 관리할 필요 없이 코드를 실행할 수 있습니다. 이벤트 기반으로 동작하며, 요청이 발생할 때만 코드를 실행하여 비용 효율적인 운영이 가능합니다. 또한, 다양한 프로그래밍 언어를 지원하며, 자동 확장과 내장된 오류 처리 기능을 제공합니다. 이 프로젝트에서는 Lambda를 활용하여 클라이언트 요청을 처리하고 데이터를 변환하거나 데이터를 적재하기 위해 다른 서비스로 전달합니다.
3. Serverless Framework
Serverless Framework는 서버리스 아키텍처를 쉽게 구축하고 관리할 수 있도록 도와주는 오픈소스 도구입니다. AWS Lambda, API Gateway, DynamoDB와 같은 다양한 클라우드 서비스와 통합되며, 인프라를 코드로 관리할 수 있도록 지원합니다. 또한, CLI를 통해 배포는 물론, 로컬 테스트, 로깅, 모니터링 등 다양한 작업을 손쉽게 수행할 수 있어 개발 및 운영 효율성을 크게 향상시킵니다.
인프라 설정을 코드로 관리할 수 있다는 점이 개인적으로 큰 장점으로 다가왔습니다. 기존에는 AWS 서비스를 생성할 때 콘솔에서 작업을 진행했지만, 여러 설정을 거쳐 배포한 뒤 이를 잊어버리거나, AWS 콘솔 UI 변경으로 설정 과정이 달라지기도 합니다. 그러나 인프라를 코드로 관리하면 설정을 형상 관리할 수 있어 이러한 문제를 효과적으로 해결할 수 있습니다. 게다가, 인프라 설정은 CloudFormation 문법을 기반으로 작성되기 때문에 AWS 공식 문서를 그대로 참고할 수 있어 이해하기 쉬우며, AWS의 최신 업데이트도 빠르게 반영할 수 있다는 장점이 있습니다.
이 프로젝트는 Lambda를 포함한 서버리스 기반 코드 베이스와 이와 연결된 다양한 서비스가 존재하기 때문에 Serverless Framework를 사용하기에 적합한 환경이라고 판단했습니다.
4. 프로젝트 설정
개발 환경
- Nodejs : 22.12.0 (Node.js 버전은 AWS Lambda에서 지원하는 버전을 선택합니다.)
- pnpm : 9.15.2
- Serverless Framework : 4.4.18
Serverless Framework 설치
먼저, Serverless Framework를 설치합니다. 글로벌로 설치하는 것을 권장하며, 아래 명령어를 실행합니다.
$ pnpm add -g serverless
설치가 완료되었는지 확인하려면 다음 명령어를 실행하여 버전을 확인합니다.
$ sls --version
프로젝트 생성
이제 Serverless Framework를 사용하여 프로젝트를 생성하기 위해서 아래의 명령어를 실행합니다. 명령어를 실행하면 대화형으로 옵션을 선택하게 됩니다.
$ sls
- 템플릿은 “AWS / Node.js / HTTP API”를 선택합니다.
- 프로젝트 이름은 event-log-server라고 입력합니다.
- “Create Or Select An Existing App”은 “Skip Adding An App”을 선택합니다.
생성된 프로젝트에는 package.json 파일이 포함되어 있지 않습니다. Node.js 종속성을 관리하기 위해 다음 명령어를 실행하여 package.json 파일을 생성합니다.
$ pnpm init
Git으로 버전 관리를 설정합니다. Git 초기화를 위해 아래 명령어를 실행합니다.
$ git init
사용중인 Node.js 버전을 기록하기 위해서 아래의 명령어를 실행합니다. nvm을 활용하면 해당 파일을 통해 프로젝트에서 권장하는 Node.js 버전을 쉽게 적용할 수 있습니다.
$ node -v > .nvmrc
# .nvmrc에 설정된 버전으로 변경합니다.
$ nvm use
프로젝트 구조 살펴보기
프로젝트의 handler.js 파일을 살펴보면 아래와 같은 코드가 작성되어 있습니다. 이 함수는 특정 트리거, 예를 들어 API Gateway를 통해 HTTP 요청이 들어올 때 실행됩니다.
exports.hello = async (event) => {
return {
statusCode: 200,
body: JSON.stringify({
message: "Go Serverless v4! Your function executed successfully!",
}),
};
};
그리고 serverless.yml 파일을 살펴보면 아래와 같이 되어 있습니다.
org: YOUR_ORG
service: event-log-server
provider:
name: aws
region: ap-northeast-2
runtime: nodejs20.x
functions:
hello:
handler: handler.hello
events:
- httpApi:
path: /
method: get
provider는 사용할 클라우드 제공자와 해당 서비스에 필요한 설정을 정의하는 부분입니다. 여기에는 리전, 런타임, IAM 역할, 환경 변수 등을 포함하여 클라우드 환경을 구성하는 데 필요한 핵심 설정을 지정합니다. 위의 설정은 AWS를 사용하며, 리전은 ap-northeast-2, 런타임은 Nodejs v20을 사용한다는 것을 나타냅니다. provider와 관련된 더 많은 내용은 여기서 확인할 수 있습니다.
functions는 배포할 서버리스 함수를 정의하는 부분입니다. 여기에는 각 함수의 이름, 실행될 코드의 핸들러 경로, 그리고 함수가 호출되는 이벤트 소스(API Gateway, S3 이벤트 등)를 설정합니다. 위의 설정은 hello라는 함수가 정의되어 있고 실행될 코드는 루트에 있는 handler.js의 hello 함수이며, HTTP GET 요청이 / 경로로 들어올 때 된다는 것을 나타냅니다. functions와 관련된 더 많은 내용은 여기서 확인할 수 있습니다.
Serverless Framework 이해하기 - 테스트
작성한 코드를 테스트하기 위해 Serverless Framework CLI에서 제공하는 명령어를 사용할 수 있습니다. 이 명령어를 통해 serverless.yml에 등록된 함수를 로컬에서 실행할 수 있습니다. 기본적으로 등록되어 있는 hello 함수를 실행해보겠습니다. 여기서 local은 아직 배포되지 않은 함수를 실행한다는 의미 입니다.
$ sls invoke local --function hello
# 파라미터는 --data를 통해서 전달할 수 있습니다.
$ sls invoke local --function --data '{"name": "seonming"}'
# 또는 --path을 통해서 JSON 파일의 데이터를 전달할 수 있습니다.
$ sls invoke local --function --path data.json
위의 명령어는 로컬에서 단순히 함수를 실행하는 것이기 때문에 실제 배포 환경을 완벽히 재현할 수 없습니다. 예를 들어, 위와 같이 파라미터를 전달하면 함수의 파라미터로 그대로 전달되지만, HTTP API로 배포된 경우에는 파라미터가 Path Parameter, Query String, Body로 구분됩니다. 따라서 실제 배포 후 실행 환경과 차이가 있을 수 있습니다. 이 문제를 해결하려면 API Gateway에서 파라미터가 어떻게 전달되는지 확인하고, 그 구조에 맞게 파라미터를 직접 전달해야 합니다. 그러나 이는 다소 번거로운 과정입니다. 다행히도 이를 간단하게 해결할 수 있는 플러그인이 있는데요, 바로 serverless-offline입니다. serverless-offline은 실제 배포 환경과 유사하게 API Gateway와 Lambda의 동작을 에뮬레이션하여, 로컬에서 HTTP 요청을 테스트하고 디버깅할 수 있는 기능을 제공합니다.
플러그인을 설치할 때는 패키지 매니저(pnpm, npm 등)를 사용할 수도 있지만, Serverless Framework CLI에서 제공하는 전용 명령어를 사용하는 것이 더 간편합니다. 플러그인은 설치한 후 serverless.yml에 추가해야 되는데 이 명령어를 사용하면 플러그인을 설치하는 동시에 serverless.yml 파일에 자동으로 플러그인 설정이 추가되기 때문에 편리합니다.
아래의 명령어를 통해 serverless-offline 플러그인을 설치합니다.
$ sls plugin install --name serverless-offline
이제 serverless-offline을 사용해 프로젝트를 실행하면 로컬 환경에서 서버가 시작됩니다. 출력되는 엔드포인트를 통해 요청을 보내면 연결된 함수가 실행됩니다. 또한, 함수에서 pathParameters, queryStringParameters, body 등 다양한 요청 정보를 확인할 수 있습니다.
$ sls offline
$ curl "http://localhost:3000?name=seongmin"
$ curl \
-X POST \
-H "Content-Type: application/json" \
-d '{ "name": "seongmin" }' \
http://localhost:3000
**추가적으로, Serverless Framework CLI에서 제공하는 sls dev 명령어를 사용하는 방식도 있습니다. 이 명령어를 사용하면 API Gateway와 같은 원격 리소스를 통해 들어오는 요청을 실시간으로 로컬 함수로 라우팅하여, 배포된 리소스를 활용하면서도 로컬에서 개발과 테스트를 진행할 수 있습니다. sls dev 를 실행한 후 AWS 콘솔에 접속해서 확인해보면 API Gateway와 Lambda 함수가 배포되어 있는 것을 확인할 수 있습니다. 하지만, Lambda 함수에 배포된 코드를 보면 로컬에 작성한 코드가 아니라 다른 코드가 들어가 있는데요. 이 코드가 sls dev 를 실행하여 세션을 연결하고 있는 동안 로컬 머신으로 라우팅하는 역할을 하는 것으로 보입니다. 실제 코드가 배포된 것이 아니기 때문에 sls dev 를 종료하면 동일한 엔드포인트로 호출해도 동작하지 않습니다.
$ sls dev
Serverless Framework 이해하기 - 배포
배포는 Serverless Framework CLI에서 지원하는 명령어를 통해 간단하게 진행할 수 있습니다. 이 명령어는 serverless.yml에 참조하여 AWS CloudFormation 템플릿을 생성하고 이를 기반으로 필요한 리소스를 배포합니다.
$ sls deploy
배포가 완료되면 호출할 수 있는 엔드포인트를 확인할 수 있습니다. sls info 명령어를 사용하면 엔드포인트와 함께 배포된 서비스의 이름, 리전, 함수 이름 등의 세부 정보를 확인할 수 있습니다.
$ sls info
실제 서비스에서는 운영 환경과 개발 환경을 분리해야 합니다. 이럴 때 --stage 옵션을 사용합니다. --stage 옵션을 생략하면 개발 환경(dev)으로 인식하기 때문에, 위의 명령어는 sls deploy --stage dev 와 동일합니다. 하지만 --stage 값은 사용자가 자유롭게 지정할 수 있어, prod, production, dev, development 등 어떤 값이든 지정할 수 있습니다. 그렇기 때문에 이 옵션을 사용할 땐 정확한 네이밍 컨벤션을 정해야 합니다.
$ sls deploy --stage development
$ sls deploy --stage production
--stage 옵션으로 전달한 값은 serverless.yml에서 ${opt:stage}로 참조할 수 있습니다. 이를 활용하면 환경별로 서로 다른 설정을 손쉽게 적용할 수 있습니다.
다음 글에서는
이번 글에서는 데이터 수집을 위한 AWS 서비스와 Serverless Framework에 대해 간단히 살펴보았습니다. 또한, Serverless Framework를 사용해 프로젝트를 생성하고, 이를 테스트 및 배포하는 방법도 알아보았습니다. 다음 글에서는 본격적으로 코드를 작성하고 배포 과정을 다뤄보겠습니다.
2025.01.04 - [이벤트 로그] - 이벤트 로그 서버 구축 (1) - 개요
2025.01.11 - [이벤트 로그] - 이벤트 로그 서버 구축 (2) - 데이터 수집 파트 1
2025.01.18 - [이벤트 로그] - 이벤트 로그 서버 구축 (3) - 데이터 수집 파트 2
2025.01.25 - [이벤트 로그] - 이벤트 로그 서버 구축 (4) - 데이터 적재 파트 1