서버리스, 람다, SQS를 이용한 프로젝트3

문한성·2023년 5월 26일
0

부트캠프

목록 보기
96/123
post-thumbnail

프로젝트 개요

AWS 클라우드 환경을 기반으로 하는  느슨하게 연결된 (loosely coupled) 어플리케이션 아키텍처에 대한 이해


프로젝트 요구사항 및 시나리오

프로젝트 명 : <자동 재고 확보 시스템> 을 위한 MSA 구성


Day 3

목표

Factory-API 문서

Factory-API Document

Method

  • POST

Path

  • /api/manufactures

Request Body Schema : application/json

{

MessageGroupId : string(메시지 그룹 아이디) //"stock-arrival-group",

MessageAttributeProductId : string(추가 생산이 필요한 제품 아이디),

MessageAttributeProductCnt : string(추가 생산 요청 수량),

MessageAttributeFactoryId : string(추가 생산을 요청할 공장 아이디),

MessageAttributeRequester : string(추가 생산 요청 담당자)

CallbackUrl : string(생산 내역으로 데이터베이스에 재고를 추가할 서버의 주소)

}

Step 4 : 데이터베이스의 재고를 증가시키는 Lambda 함수 생성

#1. 데이터베이스의 재고를 증가시키는 Lambda 함수 (stock-increase-lambda)를 배포

const serverless = require("serverless-http");
const express = require("express");
const app = express();
app.use(express.json())

const {
  connectDb,
  queries: { getProduct, increaseStock }
} = require('./database')

app.post("/product/donut", connectDb, async (req, res, next) => {
  const [ result ] = await req.conn.query(
    getProduct(req.body.MessageAttributeProductId || 'CP-502101')
  )
  if (result.length > 0) {
    const product = result[0]
    console.log("req.body = ", req.body)
    const incremental = req.body.MessageAttributeProductCnt || 0

    const queryResult = await req.conn.query(increaseStock(product.product_id, incremental))
    console.log('입고성공! result = ', queryResult);
    return res.status(200).json({ message: `입고 완료! 남은 재고: ${product.stock + incremental}`});
  } else {
    return res.status(400).json({ message: "상품 없음" });
  }
});

app.use((req, res, next) => {
  return res.status(404).json({
    error: "Not Found",
  });
});

module.exports.handler = serverless(app);
module.exports.app = app;

#2. stock_lambda 에서 레거시 시스템 (Factory API) 에 제품 생산 요청

  • Factory-API 문서를 활용한 코드작성
  • npm install axios 을 통한 axios 라이브러리 (stock-increase-lambda 에서)

=> axios 이란? promise 기반 비동기 방식의 HTTP 요청 처리

  • const axios = require('axios').default 을 소스코드 맨 위에 작성
  const axios = require('axios').default
  
const handler = async (event) => {
  let newevent = JSON.parse(event.Records[0].body)
  console.log(event);
  console.log("event : ", newevent);

  await axios.post('http://project3-factory.coz-devops.click/api/manufactures', {
      "MessageGroupId": 'stock-arrival-group',
      "MessageAttributeProductId": 'CP-502101',
      "MessageAttributeProductCnt": 3,
      "MessageAttributeFactoryId": 'FF-500293',
      "MessageAttributeRequester": 'name',
      "CallbackUrl": 'increase람다 api gateway arn'
  })
      .then(function (response) {
        console.log("성공");
      })
      .catch(function (error) {
        console.log(error);
  });
}

module.exports = {
  handler,
};

#3. curl 명령을 통한 재고 생산 요청

  • 재고 소진 후 재요청 시 재고 생산요청 됨
  • 생산 완료 확인 후 재요청 하여 구매 확인

#4. 추가 시나리오에 대한 아키텍처 구성 추가

a. 광고 중단 요청 진행 시나리오

재고가 없는 상황에서도 광고가 계속 진행되고 있습니다.
광고 비용 절감과 고객불만을 낮추기 위한 조치가 필요합니다.
메시지가 유실되는 상황을 막기 위해 내구성을 갖춘 시스템이 필요합니다.

  • 요구사항
    • 재고를 채우기 위한 과정이 진행될 때 광고 담당자에게 광고 중단 요청 내용을 담은 이메일이 전송되어야 합니다.
    • 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 합니다.
    • AWS SES 서비스를 이용해서 이메일을 전송해야 합니다.

b. VIP 고객관리 프로세스 추가 시나리오

모니터링 결과 대량 주문을 하는 일부 고객들이 확인되었습니다.
대량 구매 고객들의 사용자 정보를 식별할 수 있어야 합니다.
고객정보는 별도의 서버(EC2)와 데이터베이스(RDS)에서 관리되고 있습니다.
데이터베이스 기록과 외부 마케팅 시스템으로의 연결과정의 오류를 대비하기 위한 내구성 갖춘 시스템이 필요합니다.

  • 요구사항
    • 100개 이상 구매가 발생 시 해당 유저의 타입이 normal에서 Vip로 변경되어야 합니다.
    • 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 합니다.
    • 고객관리는 별도의 데이터베이스(RDS)로 관리되고 있기 때문에 해당 데이터베이스에 접근해서 정보를 수정해야 합니다.

profile
기록하고 공유하려고 노력하는 DevOps 엔지니어

0개의 댓글