4. 고려사항 1
• API 서버가 아닌 단순한 구조의 푸시 배치잡 서버
• 웹플룩스 기반의 푸시토큰 관리 API 서버에서 개발했던 코드의 재사용
• 병렬처리를 위한 물리적 장비/논리적 디비 구조를 고려하고 싶지 않다.
고려사항 2
• Block 연산을 사용할까 ? 사용하지 말까 ?
• Eventloop thread 기반에서 동작 안해도 되는건가 ?
테스트 조건
• mongo sharding cluster 환경
• 테스트 디바이스는 130만대
1. 목표: 천만 사용자에게 푸시를 5분 이내에 보내자
17. 2. 구현방식: Custom ThreadPooling
• 가장 뛰어난 성능을 보여줌
• 로그 가독성이 뛰어남
• 순차적으로 특정 쓰레드가 어떤 디바이스에 접근할지 알 수 있어서 모니터링도 수월함
• 스스로 제어했음에 뿌듯함
• 코드량은 30 라인에서 -> 250 라인으로 증가
• BackPressure의 지원 api를 사용 못 해 코드가 지저분해짐
• 향후 더 복잡한 호출이 추가될 경우 대응하기 어려움
• 향후 유지보수자는 어떤 코드를 더 어려워할까 ?
18. 3. 비교
Single Thread Reactive Reactive + BackPressure ThreadPooling
352초 측정실패 78초 42초
• 성능
• 코드량
Single Thread Reactive Reactive + BackPressure ThreadPooling
10라인 30라인 30라인 250라인
하지만 단순 스케줄성 잡 하나의 수치이고
운영방식과 서버 전체 자원의 효율을 고려하지 않았기 때문에
이런 단순 비교는 아무 의미가 없으며
Reactive에서도 더 효율적으로 쓰레드를 운용할 수 있음
결국 공들인 쪽의 코드가 성능이 더 나올 것으로 생각됨
19. 5. 결론
• 무작정 빠른게 답이 아닐수도… (n2c 다들 적용하세요)
• 잡의 특성이 중요함, 유실 파악과 추적에 용이한 건 어떤 방식일까 ? (물리적 서버분리, 논리적 잡분리 등)
• 코드레벨의 배압도 중요하지만 아키텍처 관점에서 배압도 중요 (연관된 서버의 장애)
• 서버 전체 자원 효율관점에선 어떤 방식이 유리할까 ? (parallel, elastic, eventloop, 자체 쓰레드풀)
• 서비스 c/s 대응이 수월한 방식은 ? (발송 시점에 따른 동의여부 상태)
우위의 방식이 있는 것이 아니며 서비스 영역별 각자 맞는 방식이 가장 중요하다고
생각되며 정답이 있기보다는 서비스 스펙을 고려한 배치잡의 특성과 서버의 전체
자원 효율성(적은 쓰레드, 적은 메모리) 측면에서 선택할 거 같습니다.
20. 5. 결론
내가 사용할 쓰레드의
범위는 어디까지 일까 ?
Parallel
Elastic
TaskScheduler
IO Selector
Reactor-http-nio
EventLoopGroup
User Custom
queue
queue queue
queue queue
queue
queue