MSA 프로젝트 - 2

박형석·2022년 5월 5일
0

프로젝트

목록 보기
3/4
post-thumbnail

Git


step-1-tutorial-test-k6

목표: k6를 이용한 성능 테스트

Day 1 - Step 2 에서 만든 람다함수를 이용하여 k6로 많은 요청을 보내 성능을 테스트 해본다. 테스트 코드는 여기에서 조회가능.

1. Test 실행

k6 run -u 1 -i 100 ./single-request.k6.js 명령어를 실행하여 100회의 요청을 보낸다.


그러면 100회의 요청이 실행되고 결과 값은 다음과 같이 나오게 된다.

상태코드와 요청의 결과들이 나오는데 몇 번 실행하고 실패된 요청의 갯수등이 나온다.


step-2-tutorial-dlq

목표: Dead Letter Queue(DLQ) 연습

Step-1 에서 100회의 요청을 보냈지만 만약 실패한다면 Dead-letter-queue 에 전송하게끔 handler.jsk6테스트 코드를 구성하여 요청을 보내보면 어떤 결과가 나오게 되는지 알아보자.

Step-2의 시나리오는 다음과 같다.

0. 어느날 B업무 정책회의를 하였다.

1. B업무를 진행하는, 컨슈머 람다의 알고리즘이 30초 이상이면 실패로 간주한다. 라고 개발자와 운영자가 정하였다.
    (각 요청에 따른 람다내용을 보고 오래 걸리는 것이라고 생각하면 되지만, 알고리즘이 수렴하지 않고 발산할 경우 알고리즘 처리시간이 오래 걸릴 수 있다)

2. 따라서, sqs에 visibility timeout (가시성 메시지 타임아웃시간)를 3초로 설정 한다. 

3. 30초 동안 5개의 maxReceiveCount 설정을 해주고, maxReceiveCount가 5번이 넘으면 메시지를 메시지를 위에서 정의한대로 실패로 간주되어 데드레터큐에 저장된다.
    - 참조 : sqs_deadletterqueue.js

4. 저장한 메시지는 운영자가 세부 문제를 직접 수작업으로 파악한다. 

5. 이를 테스트 하기 위해서, 20초 동안 메시지를 10개를 보낸다, 50%는 30초 롤폴링을 30초 동안 진행되도록 설정하고, 나머지는 바로 응답을 준다.

6. 결과로, 1,2*,3,4*,5,6*,7,8*,9,10* 짝수만 30초동안 롤폴링을 진행하며, 홀수는 바로 응답을 준다.
 그러면 순서대로 데드레터큐에 저장된 메시지는 이렇게 나열된다.
 2,4,6,8,10

이제 요청 테스트를 진행해보자


이동중인 메시지들이 보인다.

조금 시간이 지나게 되면 짝수번의 요청인 메시지들이 데드레터 큐에 쌓이게 될 것이다.


step-3-diagrams

목표: 시나리오를 보고 다이어그램을 완성할 수 있다.

시나리오:

## Day3 실제 구현을 대비하여 재고 관련 SNS 및 SQS를 준비합니다

- Sales API가 구매요청에 의해서 데이터베이스에서 재고 상황을 파악한다.
  - 재고가 있다면 감소시키고 응답으로 판매완료 내용을 전달합니다.
  - 재고가 없는 경우 공장에 주문을 진행합니다 (Day 3때 진행)
    - 재고가 없다는 내용을 담은 메세지 페이로드와 함께 SNS topic이 생성됩니다. (topic 이름: `stock_empty`)
      - 메세지가 SQS로 구현된 `stock_queue`에 수신됩니다.
        - DLQ 이름: `dead_letter_queue`

위 내용을 인프라로 구축하고, 다이어그램으로도 완성합니다.

실제 구현하기전 다이어그램을 작성하여 전체적인 구성을 한 눈에 알아보기 쉽게 작성할 줄 아는것은 개발자나 데브옵스 엔지니어의 덕목이라고 볼 수 있다.

이러한 다이어그램을 작성하는 툴로 draw.io툴을 사용하여 그렸다.


step-4-sales-api-service

목표: Day-1/Step-4 Sales API를 lambda 형태로 리팩토링 한 후, serverless framework로 배포할 수 있다.

리팩토링을 한 코드를 aws-lambda에 배포하여 잘 작동하는지 curl요청을 보내 확인 해보자.

1. serverless.yaml 작성

service: aws-node-sell-request
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x
  region: ap-northeast-2

  environment:
    PASSWORD: XXXXXX_secret
    HOST_RDS: XXXXXX-db-for-XXXXXXXX.XXXXXXXX.ap-northeast-2.rds.amazonaws.com
    USER_RDS: XXX_XXXX_c-3
    DATABASE_RDS: projectXXX-3

functions:
  api:
    handler: handler.handler
    events:
      - httpApi: 
          method: post
          path: /send
      - httpApi:
          method: get
          path: /status
          

plugins:
  - serverless-lift

yaml파일에 환경변수들을 설정해서 람다배포를 진행했다. 저 데이터베이스는 지금은 존재하지 않지만 원래 환경변수들을 퍼블릭으로 공개하면 안된다...

배포를 한 뒤 생성된 POST 엔드포인트를 curl요청에 담아서 다음과 같은 curl요청을 보내보자

curl --location --request POST 'https://wburch7m82.execute-api.ap-northeast-2.amazonaws.com/send' --header 'Content-Type: application/json' --data-raw '{   "MessageGroupId": "stock-empty-group",    "subject": "부산도너츠 재고 부족",  "message": "재고 부족",    "MessageAttributeProductId": "CP-502101",    "MessageAttributeFactoryId": "FF-500293"}'

그러면 판매완료라는 응답과 함께 람다 함수가 실행 되었다.

이제 클라우드와치(cloudWatc)로 로그를 살펴보자.

별다른 에러 없이 코드가 잘 실행된 것을 볼 수 있다.

로컬에서 실행되던 함수를 aws-lambda로 배포하려고 코드를 수정하는 과정에서 Credential이나 Dependency들이 필요없어지거나 따로 설치해야 하는 삽질을 겪었다.
그리고 환경변수를 어떻게 설정해야 할지도 헷갈렸는데 간단히 .yaml파일에 정의 하면 환경변수들을 잘 설정이 되었다.


step-5-stock-empty-lambda

목표: 공장 api에 추가 생산을 요청하는 메시지를 보내는 람다를 배포한다.

이번에는 트리거가 HTTP요청이 아닌 SNS에 알림이 들어오면 구독하고있던 SQS에게 메시지 큐가 보내지게 되면 그 큐가 트리거가 되어 람다 함수를 실행시키고 소비되는 구조이다.

serverless.yaml은 다음과 같이 작성되었다.

service: aws-node-post-stockEmpty
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x
  region: ap-northeast-2

functions:
  hello:
    handler: handler.Stock_Empty
    events:
      - sqs:
          arn: arn:aws:sns:ap-northeast-2:728116505069:stock_empty.fifo

event 속성에 sqs: arn이 있다.
이렇게 설정을 하게되면 트리거는 메시지 큐로 사용되게 된다.

배포를 하게되면 이전과 달리 엔드포인트가 존재하지않는 것도 트리거가 다르기 때문이다.

"use strict";
const axios = require("axios");

const Stock_Empty = async (event) => {
  let newevent = JSON.parse(event.Records[0].body)
  console.log(event);
  console.log("event : ", newevent);

  axios.post('http://factory.p3.api.codestates-devops.be:8080/api/manufactures',{ //공장 API 엔드포인트
      "MessageGroupId": 'stock-arrival-group',
      "MessageAttributeProductId": 'CP-502101',
      "MessageAttributeProductCnt": 10,
      "MessageAttributeFactoryId": 'FF-500293',
      "MessageAttributeRequester": '박형석',
      "CallbackUrl": 'https://4ubv3jsfl4.execute-api.ap-northeast-2.amazonaws.com/send' // 생산된 재고현황을 데이터베이스에 반영
  }).then((res)=>{
      console.log(res)
      //console.log(res.data)
      console.log("보내짐!!")
  }).catch(error => {
      console.log(error);
  });
}

module.exports = {
  Stock_Empty,
}

위와 같은 코드가 람다함수로 배포되었다.

만약 재고부족으로 인한 메시지 큐가 생성된다면 이 함수가 실행되어 공장API로 10개를 추가 생산해 달라는 내용을 담은 요청이 보내지게 된다.

profile
Better Than Yesterday

0개의 댓글