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 까지 하기엔 오버엔지니어링이다. 현재 상황으로는 설계로 족할 것 같다. 그래서 토이프로젝트에 미리 적용 해보고 회사에 추후 적용 해볼 수 있는 시간이 있는 것 같다.

728x90

배경

최근에 회사에서 알림톡 프로세스를 개선했다. 자세한 내용: 여기

 

알림톡 기능 퍼포먼스 개선

배경기존에 A 서버에서 B 서버로 호출 하면 써드파티 알림톡 발송업체로 호출 하고 다시 A 서버로 콜백 하는 방식이었다. (A 서버 에서는 해당 발송 결과 내역을 저장한다.) N번의 알림톡 발송 요

ydontustudy.tistory.com

 

 

알림톡 발송 후 콜백을 받아 람다에서 후처리 하는 프로세스까지는 성공적이었다. 람다에 대해 더 알아보며 Reserved Concurrency/Provisioning Concurrency 가 있었다. 여기서 파생해서 람다에 대해 더 알게 된 이후로 현재 설계로는 서비스가 장기적으로 잘 돌아가지 않을 것이고 큰 기술부채로 남겨질 것 같다고 생각해서 더 고민을 해보았다.

 

해결 방법 모색

 

Reserved Concurrency 에 대한 고민

 

람다는 동시에 1000개의 함수가 실행될 수 있는데, 해당 Region의 모든 람다가 통틀어 1000개 라고 한다. 즉, 여러개의 함수가 있을 때, 중요하지 않은 함수의 요청이 갑자기 많아지만 정작 중요한 함수에 대한 요청이 거부되면서, 실행하지 못하는 이슈가 발생할 수 있다. 그래서 전체 1000개의 pool에서 특정 중요한 함수에 할당 해놓기 위해서 Reserved Concurrency 를 설정 해둘 필요성을 느꼈다.

(추가적으로, 해당 설정으로 인해 디도스나 비용절감에도 도움이 될 것 같다.)

 

그래서 알림톡 후처리를 하는 람다 함수에 Reserved Concurrency를 300개 정도 설정 해놓고, 해당 함수에 대한 전체 요청은 어플리케이션내에서 처리하는 방향이 낫지 않을까 생각 해보았다. 해당 기능은 LB 환경에 대한 고려도 하지 않아도 된다. 왜냐하면 람다로 보내질 이벤트에 담길 정보들은 Notify가 아닌 다른 서버에서 요청을 받기 때문에 데이터 정합성이 이미 확보 돼있고, 순서에 크게 상관없기 때문이다.

 

그리고 알림톡 프로세스 개선을 V4 까지 잡아 놓았는데, V2 부터는 람다에서 메시지 큐에 들어갈 이벤트를 발행 할 예정이다. 이러한 부분에서도 내부 큐에서 번들로 람다에 요청 보내는것이 필요하다고 생각한다. 메시지 큐 이벤트 하나하나 발행할 때마다 람다에 요청하기엔

람다의 컨넥션 풀이 한정적이고 Reserved Concurrency 에 설정 된 임계값이 넘어가면 throttling이 일어나기 때문에 내부적으로 번들링 하는거는 현재 상황에서 필수불가결하지 않을까 생각해본다.

 

 

Provisioned Concurrency 에 대한 고민

 

람다를 사용하는 많은 분들이 고민하는 부분중 하나는 Cold start 일것이다. 요청을 받고 인스턴스가 띄워지는 시간 동안은 요청을 처리하지 못하기 때문에 그만큼 고객은 기다리는 시간도 정비례한다. 이거를 해결하기 위해서는 Provisioned Concurency 를 설정하면 된다. 해당 기능은 미리 Warm up 될 람다 인스턴스의 개수를 설정 하면, 바로 처리 할 수 있게 그만큼 함수를 warm up 시켜놓는다. 그러나 해당 기능은 비용이 발생한다.


개선 하려고 하는 프로세스는 실시간성을 띄고있지 않기 때문에 비용을 부담하면서 까지 해당 기능이 필요하지 않을 것 같다.

 

 

마무리

기술 하나를 도입할 때 양보다 질이라고 생각이 든다. 좋다고 하는 기술들을 이것저것 덕지덕지 붙이다 보면 미래에는 큰 부채가 될 가능성이 많을 것 같다. 그래서 최대한 많이 알아보고 테스트도 거쳐 보아야 할 것 같다.

728x90
findDateBetween(LocalDateTime arg1, LocalDateTime arg2)

 

 

이렇게 조회 했더니 안됐다. 이유를 찾아 보니

 

byte[], byte[] 로 인식한다고 한다.

 

해결 방법은

 

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>${hibernate.version}</version>
</dependency>

 

 

이걸 추가 하면 된다고 한다.

 

그래서 추가 했더니 잘 됐다.

 

그러나 굳이 추가 해서 프로젝트 용량을 더 늘릴 필요성을 못느껴서 LocalDateTime을 Date 타입으로 컨버팅 하는 정적 유틸 메소드가 있어서 해당 메소드를 사용했다.

 

 

 

참조

https://developer-syubrofo.tistory.com/289 [공부는 관성이다.:티스토리]

 

+ Recent posts