-
[LOL-DUO] Lamdba 로 데이터를 크롤링해 RDS 에 데이터 저장하기.프로젝트 2024. 1. 6. 16:24
1. 목표
2. 아키텍처 설계 과정
2.1 Lambda로 진행한 이유
2.2 Lambda가 2개로 나뉘어진 이유
2.3 JS로 진행한 이유
3. 개발 과정
3.1 VPC 내부에 Lambda 생성하기.
3.2 Lambda 함수 개발 ( JS )
1. 목표
1. FreeTier 내에서 가능하도록 구현. ( 최소한의 비용 )
2. Riot 데이터를 가져와 가공하여 RDS에 저장하기 및 내 서버 상태 체크.
3. 매 1시간 마다 돌며 결과를 Slack 으로 제공.
매 1시간 마다 Server의 상태 체크 등 정보를 가져와 Slack으로 알려주는 기능이 필요했습니다.
또한 주기적으로 Riot Data ( Version ) 등을 가져와 변경사항이 있다면 Database에 저장하고 알려주는 기능이 필요했습니다.
따라서 이를 묶어서 하나의 Job으로 만들고자 했고 Lambda가 적격이라 생각해 Lambda로 진행하였습니다.
2. 아키텍처 설계 과정
2.1 Lambda로 진행한 이유
기존에 돌고 있는 Job들이 존재해서 그곳에 추가를 하는 방법도 있었지만 해당 Job들은 Server와 동일한 EC2에서 동작하고 있기에 Server 가 죽는 상황이면 Job들도 죽는 상황일 가능성이 매우 높습니다.
Server의 상태를 지속적으로 알려주는 Job이 죽는다면 상태를 알 방법이 없기에 Server와 분리할 필요가 있다고 판단하였고, 매시간 단기간만 동작하면 되기에 Lambda를 선택하였습니다.
2.2 Lambda가 2개로 나뉘어진 이유
Lambda는 VPC 내에 생성한다면 Public Ip를 할당 받지 않습니다. 따라서 외부에 http 요청을 보낸다면 수신하지 못합니다.
하지만 RDS와 EC2 Server는 Private하게 관리를 해야합니다. 따라서 RDS에 정보를 저장하고 EC2 Server 정보를 가져오려면 VPC 내부에 Lambda를 띄워주어야 하는데, 이러면 해당 Lambda는 Riot 정보를 가져오지 못합니다.
이에 Riot 정보를 가져오고 Slack으로 Webhook을 날려주는 Lambda와 DB에 정보를 저장하고 Server 상태를 가져오는 VPC 내부의 Lambda를 각각 생성하여 역할을 나누었습니다.
물론 VPC 내부에 Nat Gateway를 설치해서 해당 Lambda가 Riot 정보까지 가져오도록 할 수 있었지만 Nat Gateway는 비용이 발생합니다. 1번 목표를 위해서 해당 방식보다는 Lambda를 2개로 나누는 것이 좋다고 판단하였습니다.
VPC 내부에서 동작하는 Lambda는 API Gateway와 연동되어 요청을 받으면 해당 정보를 DB에 저장, Server 정보를 가져와 반환해주는 API 형태로 만들었습니다. 최소한의 보안을 위해 특정 key값을 설정하였고, 해당 key가 아닌 요청은 무시하도록 설계하였습니다.
VPC 외부에서 동작하는 Lambda는 API Gateway가 필요하지 않는데, 이는 EventBridge가 1시간마다 동작시켜주면 되고 값을 반환할 필요가 없기 때문입니다.
2.3 JS로 진행한 이유
Riot 에서 제공하는 데이터가 Json 형태이기에 JS로 다루기도 편할 뿐더러 JS가 Lambda의 Cold Start Time도 낮은 편에 속해있기에 JS로 선택하였습니다.
https://mikhail.io/serverless/coldstarts/aws/languages/
3. 개발 과정
3.1 VPC 내부에 Lambda 생성하기.
Lambda를 VPC 내부에 띄우려면 AWSLambdaVPCAccessExecutionRole 권한이 필요합니다.
해당 권한은 Lamdba에 부여된 역할에서 권한 추가를 해주면 됩니다.
그런뒤 다시 구성에서 VPC에 들어가 배포할 VPC로 편집해주면 해당 VPC로 Lambda가 배포됩니다.
API Gateway는 트리거 추가를 통해 손쉽게 부착할 수 있습니다. EventBridge 또한 마찬가지입니다.
EventBridge의 Cron 표현식 사용법은 다음과 같습니다.
https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cron-expressions.html
3.2 Lambda 함수 개발 ( JS )
Lambda는 index.handler를 실행합니다.
handler에 input 또한 전달해주기 때문에 API Gateway를 통해 들어온 정보를 사용할 수 있습니다.
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/nodejs-handler.html
따라서 API Gateway를 사용하는 Lambda의 코드는 다음과 같이 구성하였습니다.
기본적으로 개발은 local에서 진행 후 zip으로 node_modules와 함께 파일들을 묶어 올리는 형태로 진행하였습니다.
// lambda 코드 class app { async start() { // logic } } export const handler = async (event, context) => { //key check 과정 진행 let body = JSON.parse(event.body); // body parse; let result = await new app().start(body.info, ...); // db 저장 및 server 정보 획득 return { statusCode: 200, body: JSON.stringify(result), }; }