serverless framework를 이용하여 간단한 Lambda 함수를 생성하고 배포합니다.
npm install -g serverless
serverless
AWS - Node.js - Starter로 생성
provider:
name: aws
runtime: nodejs18.x
region: ap-northeast-2
handler.js
코드를 생성한다. (서버 구현)module.exports.hello = async (event) => {
let inputValue, outputValue
console.log(event.body)
if (event.body) {
let body = JSON.parse(event.body)
// 추가 도전과제: body가 { input: 숫자 } 가 맞는지 검증하고, 검증에 실패하면 응답코드 400 및 에러 메시지를 반환하는 코드를 넣어봅시다.
inputValue = parseInt(body.input)
outputValue = inputValue + 1
}
const message = `메시지를 받았습니다. 입력값: ${inputValue}, 결과: ${outputValue}`
return {
statusCode: 200,
body: JSON.stringify(
{
message
},
null,
2
),
};
};
serverless deploy
를 통해 배포한다.
Rest API를 생성한다.
cURL을 통한 테스트: 입력값의 +1 반환.
다음과 같이 요청하여 함수 실행을 확인할 수 있다.
curl -X POST https://s8bpez4yvb.execute-api.ap-northeast-2.amazonaws.com --header 'Content-type: application/json' --data-raw '{ "input": 1 }'
serverless framework를 이용하여 메시지 큐(SQS)를 이용한 producer/consumer 구조를 생성하고 배포합니다.
Serverless CLI를 통한 프로젝트를 생성한다. (AWS - Node.js - SQS Worker)
Serverless.yml
레퍼런스를 참고하여 리전을 변경한다.
handler.js
를 편집한다. (컨슈머 구현)
const consumer = async (event) => {
for (const record of event.Records) {
console.log("Message Body: ", record.body);
let inputValue, outputValue
// TODO: Step 1을 참고하여, +1 를 하는 코드를 넣으세요
const message = `메시지를 받았습니다. 입력값: ${inputValue}, 결과: ${outputValue}`
console.log(message)
}
};
serverless deploy
를 통해 배포한다.
일단 먼저 test부터 한다.
const consumer = async (event) => {
for (const record of event.Records) {
console.log("Message Body: ", record.body);
let inputValue, outputValue
// TODO: Step 1을 참고하여, +1 를 하는 코드를 넣으세요
if (record.body) {
inputValue = parseInt(body.input)
outputValue = inputValue + 1
}
const message = `메시지를 받았습니다. 입력값: ${inputValue}, 결과: ${outputValue}`
console.log(message)
}
};
curl -X POST https://e2ibhxu3kj.execute-api.ap-northeast-2.amazonaws.com/produce --header 'Content-type: application/json' --data-raw '{ "body": 1 }'
for i in {1..10}; do curl -X POST https://e2ibhxu3kj.execute-api.ap-northeast-2.amazonaws.com/produce --header 'Content-type: application/json' --data-raw '1'; done
DLQ를 연결하고, K6 성능테스트 도구를 사용하여 여러 번의 producer 함수 실행을 보다 전문적으로 테스트할 수 있습니다. DLQ에 쌓이는 메시지의 현황은 AWS 콘솔에서 확인할 수 있습니다.
DLQ의 원리 이해를 이해한다.
consumer에 실행 시간을 늘리는 코드를 추가한다.
function delay(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
const consumer = async (event) => {
await delay(15000)
for (const record of event.Records) {
console.log("Message Body: ", record.body);
serverless deploy
를 통해 배포한다.task가 timeout이 걸려서 제대로 실행되지 않았다는 뜻이다.
람다 함수가 제대로 실행되려면 15초가 필요한데, 지금 이 람다 함수는 실행 제한 시간이 아래와 같이 6초로 걸려 있어서 그렇다.
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install k6
sh run.sh
1.람다에서 실행 제한 시간을 20초로 늘려준다.
일부러 문제 상황을 만들기 위해 Visibility Timeout 조정한다.
프로듀서에서 메시지 생성 후 DLQ에 도달하는 메시지 확인한다.
<도넛-스테이츠>는 온라인으로 도너츠를 판매합니다.
웹사이트를 통해서 주문 버튼을 누르는 것으로 구매(Sales API)가 가능합니다.
창고에 재고가 있다면 재고가 감소하고 구매가 완료됩니다.
유튜브스타 hoyong.LEE가 도넛-스테이츠의 도너츠가 맛있다고 영상을 올렸습니다.
그를 따르는 데브옵스 수강생들이 몰려듭니다. 주문이 급등합니다.
창고에 재고가 없기 때문에 구매가 불가능한 경우가 발생합니다.
창고의 도너츠 재고가 다 떨어지면 제조 공장에 알려서 다시 창고를 채우는 시스템을 구축해야합니다.
제조 공장인 <팩토리-스테이츠>에 주문을 요청(Leagcy Factory API)할 수 있습니다.
주문이 요청되면 일정 시간이 지난 후 창고에 재고가 증가합니다.
비효율적인 레거시 시스템 때문에 고객의 불만사항이 접수되고 있습니다.
제품별 재고부족 요청이 빈번하게 발생되고 있지만 전달 과정에서 지연과 누락 등 문제 상황이 발생하고 있습니다.
안정적으로 요청이 전달 될 수 있도록 시스템을 개선해야합니다.
비정상적으로 처리된 요청의 경우 운영팀에 상황을 알려야합니다.