[TROUBLESHOOTING] 자동 재고 확보 시스템 MSA 구축

Son_Doobu96·2023년 2월 21일
0

Project

목록 보기
3/3
post-thumbnail

Step 4 목표

SQS를 트리거로 해 Factory API에 생산을 요청하는 서비스 구현


먼저 기존 Step 3번까지의 프로세스가 잘 작동하는지를 확인 후 작업을 진행했다.

Serverless 프레임워크를 통해 새로운 람다함수를 배포할 디렉토리를 만들고 함수를 작성해 나갔다.

const axios = require('axios').default

const consumer = async (event) => {
for (const record of event.Records) {
    console.log("Message Body: ", record.body);
  
// let data = JSON.stringify(record.body)
//   console.log(data)
// let parser = JSON.parse(data)
//   console.log(parser)
//   console.log(parseInt(record.body.MessageId))
// let mData = JSON.stringify(data.MessageAttributes)
//   console.log(mData)
// let pData = JSON.stringify(mData.MessageAttributeProductId)
//   console.log(pData)
// let fData = JSON.stringify(mData.MessageAttributeFactoryId)
//   console.log(fData)
// const data = await record.body
const payload = {
    MessageGroupId : "stock-arrival-group", //"stock-arrival-group",
    MessageAttributeProductId : "ebb60806-b0bf-11ed-8e89-069658f3b1c6", //string(추가 생산이 필요한 제품 아이디),
    MessageAttributeProductCnt : "100", //string(추가 생산 요청 수량),
    MessageAttributeFactoryId : "d5f87cb3-b0bf-11ed-8e89-069658f3b1c6" , //string(추가 생산을 요청할 공장 아이디),
    MessageAttributeRequester : "손동훈", //string(추가 생산 요청 담당자)
    CallbackUrl : <https://생산 요청 엔드포인트> //string(생산 내역으로 데이터베이스에 재고를 추가할 서버의 주소)
}

  console.log("페이로드 확인: ", payload)

 
 axios.post('http://project3-factory-api.coz-devops.click/api/manufactures', payload)
.then(function (response) {
  console.log(response);
})
.catch(function (error) {
  console.log(error);
});

} 
};
module.exports = {
  consumer,
};

위의 수 많은 주석에서 알 수 있듯...ㅎㅎ JSON 참조 코드를 작성하는데 실패해서 일단 오늘은 아키텍처의 연결을 완벽하게 진행하는 것에 초점을 맞추기로 했다.

이 후 배포를 통해 함수의 작동을 확인했다.

일단 구현은 잘되어 함수가 잘 작동하는 것을 알 수 있었다.


◎ 완성 후의 아키텍처 설계

이게 첫날에 팀과 함께 만들었던 아키텍처 설계였다.

완성한 아키텍처의 구현을 확인한 지금 다행인 건 크게 다르지는 않았다는 점이고 깨달은점은 이전 아키텍처는 보안적 설계가 꽤나 허술했다는 점이었다.

방과 후 강의를 진행해 주시는 홍정민 강사님께서 나한테 이렇게 말씀해주셨다.

"말이 안돼는 이야기긴 하지만 보안, 네트워크, 리소스"중에서 하나를 빼려면 뭘 빼시겠어요?

굉장히 당황스러웠다... 저 셋중 뭐 하나라도 빠져도 되는게 있나?
일단 '리소스'를 빼는게 낫지 않을까요? 라고 대답했다.

그러자 한 번 더 물어보셨다.

"그럼 네트워크, 보안 중에서는요?"

"네트워크가 빠지면 아무것도 못하지 않나요?" 자신 있게 말했다.

"보안이 없으면 다 털릴텐데요?"

순간에는 이해가 안됐지만 서비스를 구현하면서 이해하게 되었다.
아무렇지 않게 클릭하는 이 리소스들 모든 게 사실은 돈이었다.
올바르게 공부한 DevOps라면 회사의, 나의 서비스가 안전할 수 있도록 하는 마음가짐을 가지는 게 먼저라는 생각이 들었다.

이 생각을 완전하게 적용하지는 못했지만 오늘 팀과 함께 설계 후의 아키텍처를 다시 그려보았다.
처음에는 2시간이 넘게 걸리던 것이 30분도 안돼서 뚝딱 나오게 되었다.

설계 후의 아키텍처

간단한 설명

  • 유저는 프론트엔드 페이지를 통해 상품을 주문하고 그 API 요청을 트리거로 람다가 실행되어 판매의 영역이 형성된다.
  • 재고가 부족한 경우 판매는 발생할 수 없으므로 생산 요청이 발생한다.
  • SNS를 통해 추후 서비스의 확장성과 유연성을 고려하였고 SQS를 활용해 비동기적 연결, DLQ를 이용해 메시지가 전달되지 못하는 장애 상황을 대비했다.
  • 생산이 완료되면 외부 서비스인 Factory가 요청을 통해 RDS의 재고 현황을 업데이트 한다.

발생가능한 문제점?

  • 외부 서비스의 RDS 접근? Nat gateway의 보안정책을 통해 제한된 리소스 연결을 진행하면 된다고 생각했다.
  • SNS, SQS로의 접근? SQS의 경우 엑세스 정책을 SNS의 토픽으로 제한하는 방법으로 해결할 수 있다고 생각했다.

SNS에도 같은 방법을 적용할 수 있지만 확장성과 유연성을 고려해 배치한
SNS에 하나의 람다 서비스에 대한 엑세스 정책을 허용하는 방법은 리소스의 설계 방향과 다르다고 생각하여 좀 더 깊은 고민이 필요하다는 생각이 들었다.


팀별 면접

오늘 팀별로 작성한 아키텍처와 그 아키텍처를 왜 구성했는지에 대한 간단한 면접을 진행했다. 내 생각과 답변을 정리해보면 좋을 것 같아 추가로 가져와 봤다.

  1. 왜 Lambda를 사용했는가?
  • 첫 번째 이유는 서버리스 서비스를 구현하기 위해서였다. 람다는 관리가 필요하지 않은 서버리스 서비스로써 트래픽에 따라 자동으로 관리되는 컴퓨팅 리소스이기에 해당 서비스에 람다가 적합하다고 생각했다.
  • 두 번째 이유는 비용이다. 람다의 비용에는 요청, 호출 수와 함수의 실행시간이 포함되지만 가장 중요한 건 월별 1,000,000건의 요청과 400,000GB의 실행시간이 무료로 제공된다는 점이다.
    이것이 람다를 선택함으로써 서비스의 초기 투자비용을 줄여줌으로써 서비스 정착의 안정성을 높여 줄 수 있는 중요 요인이라고 생각했다.
  1. 구현한 서비스가 무엇인가?
  • 판매와 생산의 영역으로 구분되는 서비스를 구현하였다.
    그리고 여기서 중요한 점은 판매와 생산이 "구분"된다는 점이다. 동기적으로 이어진 서비스가 아니라 구분되어진 비동기적 연결의 서비스이기 때문에
    유연한 서비스 운영과 장애 대처가 가능하다.
  1. SNS를 왜 사용했는가?
  • 위의 포스팅에서의 언급처럼 SNS의 가장 큰 장점은 토픽으로 관리되는 서비스의 유연성과 확장성에 있다고 생각한다. 따라서 유연한 서비스 운영과 추후 확장 가능성까지 고려하여 SNS를 사용하게 되었다.
  • FIFO를 사용하지 않은 이유는 우리가 설계하려는 서비스와 맞지 않는다 생각했기 때문이다. FIFO와 Standard의 가장 큰 차이는 순서를 보장하느냐 아니냐이다.
    우리가 FIFO를 선택하지 않은 이유는 제한된 처리량의 서비스를 만들고 싶지 않았고 리소스의 배치 위치상 순서의 보장이 필요하지 않았기 때문이다.
    만약 백엔드 역할을 하는 람다의 앞단에 SNS와 SQS가 위치하는 상항이라면
    순서가 매우 중요해진다, 생산과 판매의 순서가 꼬이면 안되기 때문이다.
    하지만 백엔드 뒤에 위치하는 현 설계에서 SNS와 SQS가 전달해야 하는 메시지의 종류는 "생산"이라는 하나의 키워드로 통합될 수 있기에 순서를 보장할 필요가 없다고 생각했다.
  1. SQS를 왜 사용했는가?
  • SQS는 비동기적 연결을 가능하게 해주는 메시지 큐로써 생산과 판매의 서비스 영역을 분리하기 위해 사용했다.
    만약 SQS가 아닌 API 게이트웨이를 통해 서비스가 연결되었다고 치면 동기적으로 연결된 서비스는 두 가지 문제점을 가지게 된다. 재고가 없는 경우 구매자는 어떠한 응답도 받을 수가 없다. 그리고 생산 영역 또는 판매 영역에서 장애가 발생하는 경우 두 서비스를 모두 이용 불가능하다.
    우리는 이러한 문제점을 해결하기 위해 SQS를 통한 비동기적 연결로 서비스를 구현했고 이를 통해 앞선 사례에서 발생할 수 있는 문제점을 보완하고 보다 안정적인 서비스를 구현하기 위해 SQS를 사용했다.
profile
DevOps를 꿈꾸는 엔지니어 지망생!

0개의 댓글