2. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
아이유를 좋아하는 소프트웨어 엔지니어입니다.
현재 산업기능요원 복무 중 입니다.
스포카 풀스택 엔지니어 15.09 - 현재
https://github.com/hanc1208
한창수(are)
3. 1. 메시지 전송 구조
2. 여러개 전달하기
3. RabbitMQ 사용
4. 팁
+
+
+
+
+
+
+
+
+
목차
5. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
스포카의 주요 프로덕트인 도도 메시지는
매장의 사장님이 매장에서 적립한 손님들께
문자 마케팅을 진행할 수 있는 서비스 입니다.
6. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
필요한 것들 • 메시지는 반드시 한 번 보내져야 한다.
• 메시지는 최대한 빠른 속도로 보내져야 한다. (늦어도 1시간 이내)
• 메시지는 카카오톡으로 먼저 보내본 다음 실패하면 LMS로 보내야 한다.
• 메시지를 보낼 수 있는 여러 서비스가 있다.
• 코인 (메시지 전송할 때 필요한 재화) 잔액의 정합성이 맞아야한다.
7. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
메시지 전송 구조
1. 메시지를 받을 손님을 타게팅합니다.도도 메시지 백엔드 (이하 메시지 서비스)
메시지 전송 서비스 (이하 전송 서비스)
LMS, 카카오톡 API (이하 통신사)
2. 통신사에 메시지 전송 요청을 합니다.
3. 실제로 손님에게 메시지를 전송해줍니다.
4. 전송 결과 전달
8. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
데이터베이스를
큐로 사용
1. 자주 사용하는 기술이어서 빠른 속도로 개발할 수 있을 것이라 예상했습니다.
2. FOR UPDATE 문을 사용하면 락을 걸 수 있어
메시지를 여러번 전송하는 일을 없앨 수 있습니다.
3. 생각보다 부하가 큽니다. 보내면 보낼 수록 느려집니다.
4. 코인의 정합성을 위해
메시지 서비스에서는 데이터베이스를 사용해야했습니다.
9. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
도도 메시지 백엔드 - 메시지 전송 구조
전송 서비스
메시지
메시지
메시지
메시지
메시지 서비스
메시지
워커 1
워커 2
메시지
워커 3
메시지
10. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
Pros • 여러개 보내는 것 보다는 생각할게 적어져 구현 속도가 빠르다.
• 여러개 보내다 실패하는 것 보다 하나 보내다 실패하는게 오류 비율이 더 낮다.
11. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
Cons • 한 번에 여러개를 처리할 수 있는 작업을 나눠하다 보니 매우 느리다.
• 쿼리를 매우 자주하니 데이터베이스에 부하가 크다.
• 어쨌든 메시지 전송은 최대한 받지 못하는 사람이 없도록 설계해야하기 때문에
하나 실패하는 것도 치명적이다.
13. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
• 전송 서비스가 메시지를 보내는 속도보다
메시지 서비스가 전송 서비스에 전달하는 속도가 느리다.
• 일단 전송 서비스에 전달하는 속도부터 개선하자.
14. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
도도 메시지 백엔드 - 메시지 전송 구조
전송 서비스
메시지
메시지
메시지
메시지
메시지 서비스
메시지
워커 1
메시지
메시지
메시지
15. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
대량 전송 방법 • SQLAlchemy ORM 대신 Core 사용 (약 10배 빠름)
16. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
대량 전송 방법 • SQLAlchemy 커밋할 때 만료시키지 않도록
• SQLAlchemy 자동 Flush 해제
SELECT 쿼리 실행!
UPDATE 쿼리 실행!
17. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
Gevent • 동시성 라이브러리
• C 확장 모듈로 제공되는 경량 코루틴
• 한번에 오직 하나의 스레드만 실행됨
• 모든 비동기 모듈을 자동으로 Mocking
• 데이터베이스나 HTTP 요청이 있으면 기다리지 않고 다른 코루틴 실행
26. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
RabbitMQ • 메시지 브로커
• 생산자가 메시지를 큐에 저장해두면,
소비자가 메시지를 가져와 처리
27. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
사용한 이유 • HTTP 요청은 실패하면 재전송 해주어야합니다. -> 코드 복잡해짐
• RabbitMQ는 명시적으로 메시지를 큐에서 제거해야만 하게 설정할 수 있습니다.
• 처리에 성공하면 메시지를 큐에서 제거합니다.
• 처리에 실패하면 메시지를 큐에서 제거하지 않습니다.
• 멱등성만 보장해주면 계속 재시도하면 되므로 안정적으로 처리 가능!
• 먼저 전송 결과 보내주는 곳에 사용해보자!
28. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
전송 결과 처리
전송 서비스에서 전송 결과를 큐에 넣음
메시지 서비스에서 전송 결과를 큐에서 받음
처리 성공하면 큐에서 메시지 제거
29. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
전송 (미래)
메시지 서비스에서 전송할 메시지를 큐에 넣음
전송 서비스에서 메시지를 큐에서 받음
전송 성공하면 큐에서 메시지 제거
30. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
멱등성은? 카카오와 LMS 모두 식별자를 통해 여러번 보내지지 않도록 할 수 있어 해결!
31. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
결과 • 데이터베이스 부하가 매우 적어져 빠른 속도로 전송할 수 있게 되었습니다.
3배 정도의 성능 향상을 보였습니다.
• 서버가 일을 적게해서 서버 비용이 감소했습니다.
• 오류가 발생할 확률이 현저히 감소하였습니다.
0.5% ~ 1.0%였던 오류 발생이 0%로 감소하였습니다.
(메시지는 1개라도 가지 않으면 치명적 입니다.)
• 멱등성이 보장되어 오류가 나도 재전송 하기 매우 쉬워졌습니다.
기존에는 오류가 나면 실제로 메시지의 전송 여부를 확인해야했습니다.
• 전송 속도가 느려 사용하기 힘들었던 고객이 매우 많은 매장이 도도 메시지를 사
용할 수 있게 되어 매출이 올랐습니다.
33. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
AutoScaling • 메시지 전송과 같은 서비스는 평소에는 할 일이 거의 없지만,
가끔 매우 많은 일을 해야합니다.
• 이럴 때에는 Auto Scaling을 사용하여
필요할 때에만 서버를 많이 사용하는 방법으로 비용을 줄이는 것이 좋습니다.
• Serverless (Lambda)도 좋은 선택입니다.
34. 스포카 크리에이터 컨퍼런스 Hello World! 문자 메시지 전송 최적화하기
Partitioning • 데이터베이스를 큐로 사용할 경우에는 파티셔닝을 사용하면 좋습니다.
한 테이블을 특정 기준에 따라 여러 테이블로 나눠주어 쿼리 속도가 향상됩니다.