728x90

이슈

https://ydontustudy.tistory.com/193 해당 글에서, 알림톡 발송 후처리 로직이 있는 람다 함수에 Reserved Concurrency/Provisioning Concurrency 를 적용 해서 백앤드 어플리케이션 내부 큐를 사용하면 될 것 같다는 의견을 냈었다. 그러나 이 방법은 서버 배포 단계에서 문제가 있었다. 그래서 해결 방법을 고안한 과정과 그 중 적용한 방법을 소개해보겠다.

 

 

해결 방법 모색

  • 배포 전에 해당 EC2 서버에 내부 queue에 있는 이벤트 모두 소모 시키는 API 호출 후, graceful shutdown 시키는 방법

CD(Continuous Deployment) 과정에서 서버를 내리기 전에 서버 내부 큐에 쌓여 있는 이벤트 들을 모두 처리 해라는 API 를 호출 후 새로운 버전의 서버를 빌드/실행 시키는 방법을 생각 해봤다. 장점은 외부 서비스를 사용하지 않고 코드로만 문제를 해결할 수 있고, 그에 따라 비용절감에 도움이 될거라고 생각한다. 반대로 단점은 많은 공수가 들어간다. Graceful shutdown 적용, Jenkins 스크립트 파일 수정, 내부 큐 이벤트 모두 소모 API 추가 등 많은 공수가 들 것으로 판단되었다. 또한 서버에 부하를 준다.

 

  • 메시지 큐 사용

메시지 큐를 사용하면 producer인 서버의 상황에 따라 유실되는 이벤트에 대한 걱정을 덜 수 있다. 그리고 무엇 보다 꼭 메시지 큐를 사용 하고자 했던 이유는 서버에 부하를 주지 않기 위함이다. 각각의 역할을 분리해서 부하를 줄이는 것이 목표 이었기 때문에, 알림톡 이벤트 발행의 역할을 지닌 서버와 해당 이벤트를 처리하는 메시지 큐의 역할을 분리 함으로서 자바 서버의 부하가 현저히 줄어들 수 있다고 생각했다. 단점은 비용이 들고 외부에 의존적으로 된다는 점을 생각해볼 수 있었다. 그러나 백 앤드 퍼포먼스를 높일 수 있기 때문에 트레이드 오프가 가능하다는 생각이었다. 

 

 

해결

API gateway 와 consumer인 람다 사이에 메시지 큐를 사용하였고, 실패한 이벤트는 Dead Letter Queue 에 보관 후 처리 되는 프로세스로 개선 하였다.

 

프로세스 종류는 다음과 같다.

  1. Source Queue 적재
  2. 람다 함수 (Consumer) 실행 하여 들어 오는 이벤트 처리
  3. Dead Letter Queue에 실패 한 이벤트 적재

 

Source Queue 에서 람다 함수로 가는 동안 람다 함수에 문제가 생겨 NACK 발생하면 해당 실패 이벤트가 DLQ 적재 되는 반면, 만약 ACK 발생하면 람다 함수에 이벤트가 전달 되어서 처리 한다. 혹시 람다 함수에서 처리 중에 에러가 발생하면, DLQ 적재 되는 프로세스이다.
DLQ 쌓인 이벤트 처리는 서버에 API 뚫어 놓고, 버튼 하나로 팀원 전체가 시스템문의에서 처리가 가능하게끔 범용적인 기능을 제공 예정이다. (발송 실패한 알림톡은 버튼 하나로 발송 가능하게끔 추상화) 해당 버튼이 트리거가 되고, 트리거가 발생 하면 SQS 에서 리드라이브(redrive)가 수행되어서 DLQ 에 있는 모든 이벤트가 다시 Source Queue 로 들어 가 다시 처리하는 방식이다.

 

마무리

끝 없는 고민의 반복이다. 꼬리에 꼬리를 물고 문제점들이 생각난다. 그러다가 모든 전력이 꺼져서 이벤트 유실이 발생하면 어떡하지? 라는 고민까지 갈 수 있을 것 같다. 이러다 심하게 탈모 올 것 같다. 가끔은 머리를 식혀줘야겠다.

아직까지 V1.7 까지의 설계이고 V4 까지 설계 해놓았다. 회사로 들어 오는 트래픽은 V4 까지 하기엔 오버엔지니어링이다. 현재 상황으로는 설계로 족할 것 같다. 그래서 토이프로젝트에 미리 적용 해보고 회사에 추후 적용 해볼 수 있는 시간이 있는 것 같다.

+ Recent posts