IT STUDY LOG
[SECTION3] <마이크로서비스> DAY 2 LOG 본문
# Achivement Goals
- 메시지 큐의 Pub/Sub 패턴과 Producer/Consumer 패턴의 차이를 이해한다
- DB와 서버와의 통신이 가능하도록 연결한다
- 특정 상황에서 SNS, SQS로 메시지가 전달되도록 시스템을 구성한다
- SQS에 들어온 메시지를 레거시 시스템(Factory API)으로 전달하는 시스템을 구성한다
- 레거시 시스템(Factory API)의 콜백 대상이 되는 리소스를 생성해 데이터베이스에 접근할 수 있게 한다
# PROJECT LOG
Project - Step 1
Step 1:Lambda 서버(Sales API) - DB 연결
1. sales-api 디렉토리에서 Sales API 확인
2. 데이터베이스 연결
- 로컬 : .env 파일 이용
- AWS : Lambda 구성 -> 환경변수 이용
- HOSTNAME=projectdb.secret.region.rds.amazonaws.com
- USERNAME=username
- PASSWORD=password
- DATABASE=database
3. 연결 후 레포지토리의 sales-api/init.sql을 참고하여 자신의 데이터베이스에 테이블을 생성하고 재고를 추가
$ mysql -u user -h projectdb.ap-northeast-2.rds.amazonaws.com -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 101
Server version: 8.0.32 Source distribution
Copyright (c) 2000, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
4. CURL 요청을 통해 데이터베이스의 재고 정보에 따라 다른 응답을 보내는 것을 확인
# endpoint는 sls deploy 후 확인 가능
# url + 요청 메소드 엔도프인트
$ CURL -X GET https://xxxxxxx.execute-api.ap-northeast-2.amazonaws.com/product/donut
{
"product_id":"e7b5da50-fa94-11ed-8923-0aebfd403c0e",
"name":"부산도너츠",
"price":19900,
"stock":3,
"BIN_TO_UUID(factory_id)":"c5544aea-fa94-11ed-8923-0aebfd403c0e",
"BIN_TO_UUID(ad_id)":"c68f5c70-fa94-11ed-8923-0aebfd403c0e"
}
Project - Step 2
Step 2: “재고 없음” 메시지 전달 시스템 구성
![](https://blog.kakaocdn.net/dn/qX4AN/btshhIQVmsR/r2eEFS53oneK7CHSrXig1k/img.png)
1. DB에 재고가 없을 경우 재고가 없다는 정보를 알리기 위한 SNS 토픽(stock_empty) 생성
1-1. AWS Console에서 SNS 주제 생성
![](https://blog.kakaocdn.net/dn/uS6ET/btshrAbXalu/8aMLJUK6PBF85fafrHUkK1/img.png)
1-2. (Optional) IaC(Terraform)을 사용해 구성
2. stock_empty 토픽을 구독하는 SQS(stock_queue) 생성
2-1. AWS Console에서 SQS 생성
![](https://blog.kakaocdn.net/dn/cxi1iz/btshpAK6hSX/rcc56GgbIk1suqW8GAlM50/img.png)
2-2. AWS Console에서 SNS 구독 생성
![](https://blog.kakaocdn.net/dn/bpeezh/btshiaM6gcX/MDKyjKjGoXTDLtBkhFhGg0/img.png)
2-3. (Optional) IaC(Terraform)을 사용해 구성
3. code snippet을 활용하여 재고 부족 메시지를 SNS에 발행
3-1. handler.js 파일 수정
// ../project3-msa/sales-api/handler.js
// .. 상략 ..
// [!] 추가
const {
alertSNS
} = require('./aws')
// .. 중략 ..
app.post("/checkout", connectDb, async (req, res, next) => {
const [ result ] = await req.conn.query(
getProduct('CP-502101')
)
if (result.length > 0) {
const product = result[0]
if (product.stock > 0) {
await req.conn.query(setStock(product.product_id, product.stock - 1))
return res.status(200).json({ message: `구매 완료! 남은 재고: ${product.stock - 1}`});
}
else {
// [!] 추가
await alertSNS(product.product_id, product.factory_id)
await req.conn.end()
return res.status(200).json({ message: `구매 실패! 남은 재고: ${product.stock}`});
}
} else {
await req.conn.end()
return res.status(400).json({ message: "상품 없음" });
}
});
// .. 하략 ..
3-2. aws 리소스 관련 메서드 모듈인 aws.js 파일 생성
// ../project3-msa/sales-api/aws.js
// aws-sdk v2 사용
const AWS = require("aws-sdk") // STEP 2
const sns = new AWS.SNS({ region: "ap-northeast-2" }) // STEP 2
const alertSNS = async (product_id, factory_id) => {
const now = new Date().toString()
const message = `도너츠 재고가 없습니다. 제품을 생산해주세요! \n메시지 작성 시각: ${now}`
const params = {
Message: message,
Subject: '도너츠 재고 부족',
MessageAttributes: {
MessageAttributeProductId: {
StringValue: product_id,
DataType: "String",
},
MessageAttributeFactoryId: {
StringValue: factory_id,
DataType: "String",
},
},
TopicArn: process.env.TOPIC_ARN
}
const result = await sns.publish(params).promise()
}
module.exports = {
alertSNS
}
3-3. CURL을 통해 재고가 없을 때까지 요청을 보내보고 재고가 없는 경우 stock_queue에 메시지가 들어온 것을 확인
$ CURL -X POST https://xxxxxxxxxx.execute-api.ap-northeast-2.amazonaws.com/checkout
![](https://blog.kakaocdn.net/dn/bUtvkp/btshp3TAXOB/XuReZhqKv5kafhcrLXQBhK/img.png)
![](https://blog.kakaocdn.net/dn/Qf3DM/btshkaGogGt/DCo6yIFeRQT2uGZtXoXExK/img.png)
![](https://blog.kakaocdn.net/dn/djrujB/btshh7JMgCr/kQtL8QnltnQt65AX3vTHj1/img.png)
Project - Step 3
Step 3-1: About DLQ
Step 3 -2: 메시지를 Factory API로 전송하는 Lambda 구성 및 DLQ 추가
![](https://blog.kakaocdn.net/dn/d3X8rg/btshjdh2vj8/GblkDz1sDv0UvZymZIKVUk/img.png)
1. 가용성을 높이기 위해 dead_letter_queue(DLQ)를 생성하고 stock_queue에 연결
![](https://blog.kakaocdn.net/dn/n4jiK/btshkxOUFAS/7f4y4N1XvU1JM8i0wFEaG0/img.png)
2. stock_queue에 들어온 메시지를 소모하기 위한 stock_lambda 구성
2-1. serverless를 사용해 람다 함수 구성
$ serverless
# template : AWS - Node.js - Starter
# project name : stock-lambda
# deploy now : N
2-2. serverless.yml을 수정해 SQS에 도착한 메시지를 소비하는 람다 함수 구성
# serverless.yml
service: stock-lambda
frameworkVersion: '3'
provider:
name: aws
runtime: nodejs14.x
region: ap-northeast-2
functions:
api:
handler: handler.handler
events:
- sqs:
arn:
Fn::Join:
- ':'
- - arn
- aws
- sqs
- Ref: AWS::Region
- Ref: AWS::AccountId
- stock_queue # SQS명
2-3. handler.js에서 SQS 메시지 이벤트 발생 시 이벤트를 핸들링하는 메서드 작성
const AWS = require('aws-sdk');
const sqs = new AWS.SQS({ region: "ap-northeast-2" })
exports.handler = async function(event, context) {
console.log(`[event] : ${JSON.stringify(event)}`)
console.log(`[context] : ${JSON.stringify(event)}`)
// TODO factory API 처리
}
3. sales-api에 요청을 보낸 뒤 stock_queue에서 메시지가 사라지는 것과 stock_lambda에서 생성된 로그 확인
$ CURL -X POST https://xxxxxxxxxx.execute-api.ap-northeast-2.amazonaws.com/checkout
![](https://blog.kakaocdn.net/dn/bzJjD8/btshjuSbvMG/205D3EK0CQOvoYeGT4XUk1/img.png)
![](https://blog.kakaocdn.net/dn/csbBiP/btshlXfprSZ/XvmwlJdNEGhVxpMlkd692k/img.png)
# REFERENCES
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-envvars.html
AWS Lambda 환경 변수 사용 - AWS Lambda
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
https://repost.aws/knowledge-center/sns-topic-lambda
Publish a message to an Amazon SNS topic using a Lambda
I want to publish a message to an Amazon Simple Notification Service (Amazon SNS) topic from an AWS Lambda function.
repost.aws
https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/aws-jsdk-reference.html
JavaScript API 참조 - AWS SDK for JavaScript
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
'devops bootcamp 4 > project log' 카테고리의 다른 글
[SECTION3] <마이크로서비스> 회고 및 야크쉐이빙 (0) | 2023.05.30 |
---|---|
[SECTION3] <마이크로서비스> DAY 3 LOG (0) | 2023.05.26 |
[SECTION3] <마이크로서비스> DAY 1 LOG (0) | 2023.05.24 |
[SECTION3] <마이크로서비스> 프로젝트 개요 (0) | 2023.05.24 |
[SECTION2] <AWS 배포 자동화> DAY 4 LOG (0) | 2023.05.02 |