IT STUDY LOG
[SECTION3] <마이크로서비스> DAY 3 LOG 본문
# Achievment goals
1. 실습과제3 아키텍처 다이어그램 설명
- 실습과제3에 대한 아키텍처 다이어그램을 작성
- 작성 툴 : draw.io, visual-paradigm
- 구글 이미지 검색 : draw.io aws, visual-paradigm aws 키워드로 예시 확인
- 실습과제3 결과물의 아키텍처 다이어그램에 대해 팀 전체가 이해하고 있어야 함
- 위의 이해를 바탕으로 아키텍처에 대한 설명을 진행할 수 있어야 함
2. 평가질문지 답변
- 실습과제3에서 사용된 AWS 리소스들에 대한 이해
- 마이크로서비스 아키텍처 개념에 대한 이해
3. 추가 시나리오에 대한 아키텍처 구성 설명
- 추가 시나리오에 대한 아키텍처를 구성해야 함(실제 구현하지 않아도 아키텍처상에 리소스 추가 배치)
- 확장된 아키텍처를 가지고 팀의 의견을 제시할 수 있어야 함
a. 광고 중단 요청 진행
❶ 시나리오
- 재고가 없는 상황에서도 광고가 계속 진행되고 있어 광고 비용 절감과 고객불만을 낮추기 위한 조치가 필요 메시지가 유실되는 상황을 막기 위해 내구성을 갖춘 시스템이 필요
❷ 요구사항
- 재고를 채우기 위한 과정이 진행될 때 광고 담당자에게 광고 중단 요청 내용을 담은 이메일이 전송되어야 함
- 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 함
- AWS SES 서비스를 이용해서 이메일을 전송해야 함
b. VIP 고객관리 프로세스 추가 시나리오 - 요구사항
❶ 시나리오
- 모니터링 결과 대량 주문을 하는 일부 고객들이 확인되어 대량 구매 고객들의 사용자 정보를 식별할 수 있도록 변경
- 고객정보는 별도의 서버(EC2)와 데이터베이스(RDS)에서 관리되고 있어 데이터베이스 기록과 외부 마케팅 시스템으로의 연결과정의 오류를 대비하기 위한 내구성 갖춘 시스템이 필요
❷ 요구사항
- 100개 이상 구매가 발생 시 해당 유저의 타입이 normal에서 Vip로 변경되어야 함
- 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 함
- 고객관리는 별도의 데이터베이스(RDS)로 관리되고 있기 때문에 해당 데이터베이스에 접근해서 정보를 수정해야 함
# PROJECT LOG
Project - Step 4
✓ Factory-API 문서
URL
Method
- POST
Path
- /api/manufactures
Request Body Schema
- application/json
- example
{
MessageGroupId : string(메시지 그룹 아이디) //"stock-arrival-group",
MessageAttributeProductId : string(추가 생산이 필요한 제품 sku),
MessageAttributeProductCnt : string(추가 생산 요청 stock 수량),
MessageAttributeFactoryId : string(추가 생산을 요청할 공장 identifier),
MessageAttributeRequester : string(추가 생산 요청 담당자),
CallbackUrl : string(생산 내역으로 데이터베이스에 재고를 추가할 리소스의 주소)
}
Response Body Schema
- example
{
"data": {
"data": {
"CallbackUrl": string(생산 내역으로 데이터베이스에 재고를 추가할 리소스의 주소),
"MessageAttributeFactoryId": string(추가 생산을 요청할 공장 identifier),
"MessageAttributeProductCnt": string(추가 생산 요청 stock 수량),
"MessageAttributeProductId": string(추가 생산이 필요한 제품 sku),
"MessageAttributeRequester": string(추가 생산 요청 담당자),
"MessageGroupId": string(메시지 그룹 아이디) //"stock-arrival-group"
},
"id": string //"2590fca2-ee22-11ed-a5df-0242ac110002",
"reqestor": string(추가 생산 요청 담당자),
}
}
Step 4 : 데이터베이스의 재고를 증가시키는 Lambda 함수 생성
1. 데이터베이스의 재고를 증가시키는 Lambda 함수(stock-increase-lambda)를 배포
2. stock_lambda에서 레거시 시스템(Factory API)에 제품 생산 요청
- Factory API 문서를 활용해 요청 메서드 작성
- stock_lambda 프로젝트에 npm install axios 명령으로 axios 라이브러리를 설치해야 함
- axios는 node.js에서 HTTP 명령을 보내는 라이브러리 (fetch와 유사)
// ..../stock-lambda/index.js
// axios 모듈 import
const axios = require('axios').default;
exports.handler = async function(event, context) {
const body = JSON.parse(event.Records[0].body.replace(/\n|\r|\s*/g, ""));
const message = body.MessageAttributes
const payload = {
MessageGroupId : message.groupId.Value,
MessageAttributeProductId : message.productId.Value,
MessageAttributeProductCnt : message.productCnt.Value,
MessageAttributeFactoryId : message.factoryId.Value,
MessageAttributeRequester : message.requester.Value,
CallbackUrl : message.callbackUrl.Value // 재고를 증가시키기 위해 전달할 url로 이 경우 stock-increase-lambda가 됨
}
console.log(`[payload] : ${JSON.stringify(payload)}`)
axios.post(process.env.FACTORY_API, payload)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
3. Sales API에서 메시지를 SNS에 발행할 때 때 Factory API에 필요한 정보를 같이 넘길 수 있도록 Factory API에 맞게 params를 수정
// ..../sales-lambda/aws.js
const AWS = require("aws-sdk")
const sns = new AWS.SNS({ region: "ap-northeast-2" })
const alertSNS = async (product, decremental) => {
const now = new Date().toString()
const message = `도너츠 재고가 없습니다. 제품을 생산해주세요! \n메시지 작성 시각: ${now}`
const params = {
Message: message,
Subject: '도너츠 재고 부족',
MessageAttributes: {
groupId: {
StringValue: "stock-arrival-group",
DataType: "String",
},
productId: {
StringValue: product.sku,
DataType: "String",
},
productCnt: {
StringValue: decremental.toString(),
DataType: "String",
},
factoryId: {
StringValue: product.identifier,
DataType: "String",
},
requester: {
StringValue: product.manager_email,
DataType: "String",
},
callbackUrl: {
StringValue: process.env.STOCK_INCREASE_API,
DataType: "String",
},
},
TopicArn: process.env.TOPIC_ARN
}
const result = await sns.publish(params).promise()
console.log(`[result] : ${JSON.stringify(result)}`)
}
module.exports = {
alertSNS
}
4. 재고 없음 메시지 전송 이후 일정 시간 이후 다시 요청 시 재고감소 작동 확인
$ CURL -X POST https://xxxxxxxxxx.execute-api.ap-northeast-2.amazonaws.com/checkout
{"message":"구매 실패! 남은 재고: 0"}%
# 재고 생산이 완료되면 구매가 가능하게 됨
$ CURL -X POST https://xxxxxxxxxx.execute-api.ap-northeast-2.amazonaws.com/checkout
{"message":"구매 완료! 남은 재고: 0"}%
완성 다이어그램 : Factory API 및 stock-increase-lambda가 반영된 최종 아키텍처
# ISSUE LOG
[ISSUE 1] Lambda에서 axios 모듈 참조 불가
# Error Log
... "Runtime.ImportModuleError: Error: Cannot find module 'axios'" ...
상황
- serverless.yml 런타임 : node.js 14.x버전
- package.json axios 모듈 : 1.4.0버전
- npm install axios, npm install --save-dev axios 명령어를 통해 node_modules 하위에 정상적으로 axios 디렉터리 생성되어있는 상황
원인
- labmda 함수가 동작할 때 axios 모듈을 찾을 수 없음
- lambda에는 Layer라는 추가 코드, 기타 콘텐츠를 포함할 수 있는 .zip 파일 아카이브가 존재하는데 여기는 라이브러리, 사용자 정의 런타임, 데이터, 구성 파일 등 포함되는데 생성한 zip이 AWS 설명서에 언급된 디렉터리 구조와 같지 않기 때문에 이런 일이 발생할 수 있음
[!] 런타임 관련 환경 변수 확인
# process.env.LAMBDA_RUNTIME_DIR
/var/runtime
# process.env.PATH
/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin
# process.env.NODE_PATH
/opt/nodejs/node14/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules:/var/runtime:/var/task
# process.env.AWS_LAMBDA_RUNTIME_API
127.0.0.1:9001
해결 방안
1) aws layer에서 설명하는 디렉터리 구조 (nodejs/node_modules)를 따르는 zip 파일을 만들어 레이어를 생성
- Lambda 콘솔의 계층 페이지 선택
- 계층 생성을 선택
- [계층 구성(Layer configuration)]에서 [이름(Name)]에 계층 이름을 입력
- (선택 사항) 설명에 계층에 대한 설명을 입력
- 계층 코드를 업로드하려면 다음 중 하나를 수행
- 컴퓨터에서 .zip 파일을 업로드하려면 [zip 파일 업로드(Upload a .zip file)]를 선택하고 [업로드(Upload)]를 선택하여 로컬 .zip 파일을 선택
- Amazon S3에서 파일을 업로드하려면 Amazon S3에서 파일 업로드(Upload a file from Amazon S3)를 선택한 뒤 Amazon S3 링크 URL에 파일 링크를 입력
- (선택 사항) 호환 아키텍처에서 값을 하나 또는 둘 다 선택
- (선택 사항) 호환되는 런타임의 경우 최대 15개의 런타임을 선택합니다.
- (선택 사항) 라이선스의 경우 필요한 라이선스 정보를 입력
- 생성을 선택
2) 해당 함수에 생성한 레이어 추가
[ISSUE 2] serverless framework와 SAM 차이
개념
공통점
- "Serverless Framework"와 "SAM"은 모두 서버리스 애플리케이션을 개발하고 배포하기 위한 도구
차이점
1) 생태계
- Serverless Framework은 AWS뿐만 아니라 다른 클라우드 제공업체인 Azure, Google Cloud Platform 등과도 통합이 가능한 다중 클라우드 도구로다양한 클라우드 환경에서 서버리스 애플리케이션을 개발하고 배포하는 데 유연성을 제공
- SAM은 AWS에서만 사용할 수 있는 도구로, AWS 리소스와 서비스에 집중되어 있음
2)문법 및 구조
- Serverless Framework는 YAML 또는 JSON을 사용하여 서버리스 애플리케이션의 구조와 설정을 정의하고 이를 통해 함수, 이벤트, 리소스 등을 선언할 수 있음
- SAM은 CloudFormation 템플릿을 확장하여 서버리스 애플리케이션을 정의하며 SAM은 CloudFormation 템플릿과 호환되기 때문에 기존 CloudFormation 템플릿을 활용하여 작업할 수도 있음
3) 로컬 개발 및 테스트
- Serverless Framework은 로컬 개발과 테스트를 위한 내장된 기능을 제공하며 개발자는 로컬 환경에서 함수를 실행하고 테스트할 수 있음
- SAM도 로컬 개발 및 테스트를 지원하지만, Serverless Framework에 비해 제한적인 기능을 제공
4) 커뮤니티 및 생태계
- Serverless Framework은 활발한 커뮤니티와 풍부한 플러그인 생태계를 가지고 있음 이를 통해 개발자들은 다양한 통합, 디버깅, 로깅 등의 기능을 추가할 수 있음
- SAM도 커뮤니티와 일부 플러그인을 가지고 있지만, Serverless Framework에 비해 규모가 작은 편
# REFERENCES
챗 gpt
https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-message-attributes.html
https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-subscription-filter-policies.html
https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-zip-cli
https://kimtaehyun98.tistory.com/143
https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/incident-management.html
https://aws.amazon.com/ko/architecture/icons/
https://aws.amazon.com/ko/serverless/
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-envvars.html
'devops bootcamp 4 > project log' 카테고리의 다른 글
[SECTION3] <마이크로서비스> DAY 4 LOG (0) | 2023.05.30 |
---|---|
[SECTION3] <마이크로서비스> 회고 및 야크쉐이빙 (0) | 2023.05.30 |
[SECTION3] <마이크로서비스> DAY 2 LOG (0) | 2023.05.25 |
[SECTION3] <마이크로서비스> DAY 1 LOG (0) | 2023.05.24 |
[SECTION3] <마이크로서비스> 프로젝트 개요 (0) | 2023.05.24 |