Project 3: Day 1

이준석·2023년 2월 17일
0

Project 3

목록 보기
1/5

Step 1: Serverless를 이용한 Lambda 생성

serverless framework를 이용하여 간단한 Lambda 함수를 생성하고 배포합니다.

  1. Serverless 튜토리얼을 통한 프로젝트를 생성한다.
npm install -g serverless
serverless

AWS - Node.js - Starter로 생성

  1. Serverless.yml 레퍼런스를 참고하여 리전을 변경한다.
provider:
  name: aws
  runtime: nodejs18.x
  region: ap-northeast-2

  1. 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
    ),
  };
};

  1. serverless deploy를 통해 배포한다.

  2. Rest API를 생성한다.

  3. cURL을 통한 테스트: 입력값의 +1 반환.
    다음과 같이 요청하여 함수 실행을 확인할 수 있다.

curl -X POST https://s8bpez4yvb.execute-api.ap-northeast-2.amazonaws.com --header 'Content-type: application/json' --data-raw '{ "input": 1 }'

트러블 슈팅 발생




Step 2: Serverless를 이용한 Lambda - SQS - Lambda 구조 생성

serverless framework를 이용하여 메시지 큐(SQS)를 이용한 producer/consumer 구조를 생성하고 배포합니다.

  1. Serverless CLI를 통한 프로젝트를 생성한다. (AWS - Node.js - SQS Worker)

  2. Serverless.yml 레퍼런스를 참고하여 리전을 변경한다.

  3. 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)

  }
};

  1. serverless deploy를 통해 배포한다.

  2. 일단 먼저 test부터 한다.

트러블 슈팅 발생


  1. consumer에 코드를 넣는다.
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)

  }
};

트러블 슈팅 발생


  1. 프로듀서 실행 → CloudWatch를 통해 컨슈머가 메시지를 소비하는 것을 확인한다.
curl -X POST https://e2ibhxu3kj.execute-api.ap-northeast-2.amazonaws.com/produce --header 'Content-type: application/json' --data-raw '{ "body": 1 }'

트러블 슈팅 발생


  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





Step 3-1: DLQ 연결 및 K6 성능테스트

DLQ를 연결하고, K6 성능테스트 도구를 사용하여 여러 번의 producer 함수 실행을 보다 전문적으로 테스트할 수 있습니다. DLQ에 쌓이는 메시지의 현황은 AWS 콘솔에서 확인할 수 있습니다.

  1. DLQ의 원리 이해를 이해한다.

  2. 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);

  1. serverless deploy를 통해 배포한다.
    test로 값을 보내면 아래와 같이 timed out이 뜬다.

task가 timeout이 걸려서 제대로 실행되지 않았다는 뜻이다.
람다 함수가 제대로 실행되려면 15초가 필요한데, 지금 이 람다 함수는 실행 제한 시간이 아래와 같이 6초로 걸려 있어서 그렇다.

  1. 프로듀서를 반복적으로 실행 및 테스트를 진행한다.
    • k6 성능 테스트 도구 활용
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



Step 3-2: Visibility Timeout 조절과 DLQ


1.람다에서 실행 제한 시간을 20초로 늘려준다.

  1. 일부러 문제 상황을 만들기 위해 Visibility Timeout 조정한다.

  2. 프로듀서에서 메시지 생성 후 DLQ에 도달하는 메시지 확인한다.



요구사항 분석 및 초기 다이어그램 작성


<자동 재고 확보 시스템>을 위한 MSA

시나리오

<도넛-스테이츠>는 온라인으로 도너츠를 판매합니다.
웹사이트를 통해서 주문 버튼을 누르는 것으로 구매(Sales API)가 가능합니다.
창고에 재고가 있다면 재고가 감소하고 구매가 완료됩니다.
유튜브스타 hoyong.LEE가 도넛-스테이츠의 도너츠가 맛있다고 영상을 올렸습니다.
그를 따르는 데브옵스 수강생들이 몰려듭니다. 주문이 급등합니다.
창고에 재고가 없기 때문에 구매가 불가능한 경우가 발생합니다.
창고의 도너츠 재고가 다 떨어지면 제조 공장에 알려서 다시 창고를 채우는 시스템을 구축해야합니다.
제조 공장인 <팩토리-스테이츠>에 주문을 요청(Leagcy Factory API)할 수 있습니다.
주문이 요청되면 일정 시간이 지난 후 창고에 재고가 증가합니다.

상황

비효율적인 레거시 시스템 때문에 고객의 불만사항이 접수되고 있습니다.
제품별 재고부족 요청이 빈번하게 발생되고 있지만 전달 과정에서 지연과 누락 등 문제 상황이 발생하고 있습니다.
안정적으로 요청이 전달 될 수 있도록 시스템을 개선해야합니다.
비정상적으로 처리된 요청의 경우 운영팀에 상황을 알려야합니다.

요구사항 1 : 재고부족으로 인한 구매실패에 대한 조치

  1. Sales API 를 통해 요청을 받은 서버가 데이터베이스에서 재고 상황을 확인합니다.
  2. 재고가 있다면 감소시키고 응답으로 판매완료 내용을 전달합니다.
  3. 재고가 없는 경우 공장에 주문을 진행합니다.
  4. 재고가 없다는 내용을 담은 메세지 페이로드가 주제별로 생성됩니다.
    5.메세지가 느슨하게 연결된 시스템을 통해 처리될 수 있도록 따로 보관됩니다.

요구사항 2 : 메세지 누락 상황에 대한 조치

  1. 빈번한 요청으로 메세지 누락이 발생합니다.
  2. 비동기 처리를 위해 보관 된 메세지가 처리되지 않은 경우 메세지들을 체계적으로 관리할 다른 처리 공간을 생성해야합니다.
  3. 메시지 처리 보관 리소스와 처리되지 않은 메세지 처리 리소스가 연결되어야합니다.

요구사항 3 : Legacy 시스템(Factory → Warehouse) 성능문제에 대한 조치

  1. 안정적으로 이벤트가 전달 될 수 있는 시스템을 구축해야합니다.
  2. 메세지를 소비하는 리소스를 통해 Factory API가 호출됩니다.
  3. 수신된 메세지에 의해 트리거가 된 컴퓨팅 리소스가 상품 재고를 증가시킵니다.

다이어그램

0개의 댓글