#NetworkSocket
본 세션에서는 카카오 T 대리 서비스에서 소켓 통신을 담당하는 커넥션 서버를 왜 새롭게 개발하게 되었는지 말씀드리고, 새롭게 개발한 커넥션 서버의 설계와 그 구현 방법에 대해서 소개하겠습니다. 그리고 개발 과정에서 마주했던 문제들과 그 해결책들을 공유드리겠습니다.
발표자 : jay.sohn 카카오모빌리티에서 카카오 T 대리 서비스의 백엔드 개발을 맡고 있는 제이입니다.
카카오 T 대리신규 커넥션 서버 개발기손정연 Jay.sohn카카오모빌리티Copyright 2022. Kakao Corp. All rights reserved. Redistribution or public display is not permitted without written permission from Kakao.if(kakao)2022
View Slide
커넥션 서버?새롭게 개발하게 된 배경설계 및 동작 방식도입 결과
카카오 T 대리
커넥션 서버?*OUFSOBM4FSWFS6TFS$MJFOU$POOFDUJPO4FSWFS%SJWFS$MJFOUSocketSocket
커넥션 서버?*OUFSOBM4FSWFS6TFS$MJFOU$POOFDUJPO4FSWFS%SJWFS$MJFOUSocketSocketPUSHPUSHPUSH
사용 중이던 데이터센터의 지원 종료새롭게 개발한 이유
사용 중이던 데이터센터의 지원 종료- 기존 커넥션 서버는 Vert.x 프레임워크 사용 중새롭게 개발한 이유7&359
사용 중이던 데이터센터의 지원 종료- 기존 커넥션 서버는 Vert.x 프레임워크 사용 중- Vert.x의 Hazelcast가 UDP 멀티캐스트 기능에 의존새롭게 개발한 이유7&359)";&-$"45
사용 중이던 데이터센터의 지원 종료- 기존 커넥션 서버는 Vert.x 프레임워크 사용 중- Vert.x의 Hazelcast가 UDP 멀티캐스트 기능에 의존- 다른 데이터센터에서는 지원 불가새롭게 개발한 이유7&359)";&-$"45
사용 중이던 데이터센터의 지원 종료- 기존 커넥션 서버는 Vert.x 프레임워크 사용 중- Vert.x의 Hazelcast가 UDP 멀티캐스트 기능에 의존- 다른 데이터센터에서는 지원 불가- 버전업? 사용 중인 Vert.x API가 모두 바뀜새롭게 개발한 이유7&359)";&-$"45
“인프라 독립적인 구조로 새롭게 개발하자!”
요구사항
- HTTP, TCP Socket, Web Socket 통신요구사항
- HTTP, TCP Socket, Web Socket 통신- 최대 30K+ 동시 연결- 7,000 TPS요구사항
- HTTP, TCP Socket, Web Socket 통신- 최대 30K+ 동시 연결- 7,000 TPS- 인프라 독립적- 스케일 아웃요구사항
기본 구조3FEJT1VC4VC6TFS$MJFOU*OTUBODFSocket*OTUBODF*OTUBODF/...$POOFDUJPO%SJWFS$MJFOUSocket*OUFSOBM4FSWFSHTTP
기본 구조3FEJT1VC4VC6TFS$MJFOU*OTUBODF*OTUBODF*OTUBODF/...$POOFDUJPO%SJWFS$MJFOU*OUFSOBM4FSWFSSocketSocketHTTP
글로벌맵 로컬맵(Client ID, Instance Host Name) (Client ID, Socket Object)연결 상태 관리
글로벌맵- 클라이언트가 연결된 인스턴스 이름 관리- 모든 인스턴스가 공유
글로벌맵- 클라이언트가 연결된 인스턴스 이름 관리- 모든 인스턴스가 공유- Redis Strings 사용- (User / Driver ID, Instance Host Name)
- 클라이언트의 소켓 세션 객체 관리- 각 인스턴스 내부에서만 사용로컬맵
- 클라이언트의 소켓 세션 객체 관리- 각 인스턴스 내부에서만 사용- Java ConcurrentHashMap 사용- (User / Driver ID, Socket Object)로컬맵
연결 수립 연결 해제메시지 전송라이프사이클인스턴스시작인스턴스종료
인스턴스 시작3FEJT1VC4VC*OTUBODF*OTUBODF*OTUBODF....
인스턴스 시작3FEJT1VC4VC*OTUBODF*OTUBODF*OTUBODF....Subscribe Channel:Instance 1Subscribe Channel:Instance 2Subscribe Channel:Instance M
연결 수립3FEJT(MPCBM.BQ*OTUBODF.Local Map$MJFOU/
연결 수립3FEJT(MPCBM.BQ*OTUBODF.Local Map$MJFOU/3-WayHandshake
연결 수립3FEJT(MPCBM.BQ*OTUBODF.Local Map$MJFOU/3-WayHandshakeSet(Client N, Socket Object)
연결 수립3FEJT(MPCBM.BQ*OTUBODF. Set(Client N, Instance M)Local Map$MJFOU/3-WayHandshakeSet(Client N, Socket Object)
메시지 전송3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload)메시지 전송
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload)Key ‘Driver 1’메시지 전송
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload)Key ‘Driver 1’Value ‘Instance 2’메시지 전송
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload) Publish Channel: Instance 2(Driver 1, Payload)Key ‘Driver 1’Value ‘Instance 2’메시지 전송
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload) Publish Channel: Instance 2(Driver 1, Payload)Key ‘Driver 1’Value ‘Instance 2’(Driver 1, Payload)메시지 전송
3FEJT(MPCBM.BQ*OTUBODFLocal Map6TFS$MJFOU*OTUBODF3FEJT1VC4VC%SJWFS$MJFOU(Driver 1, Payload) Publish Channel: Instance 2(Driver 1, Payload)Key ‘Driver 1’Value ‘Instance 2’(Driver 1, Payload)PayloadDriver 1’sSocket Object메시지 전송
연결 해제3FEJT(MPCBM.BQ*OTUBODF.Local Map$MJFOU/
연결 해제3FEJT(MPCBM.BQ*OTUBODF. Delete(Client N, Instance M)Local Map$MJFOU/Delete(Client N, Socket Object)
인스턴스 종료3FEJT(MPCBM.BQ*OTUBODF.$MJFOUT
인스턴스 종료3FEJT(MPCBM.BQ*OTUBODF.$MJFOUTExclude from routing targets
인스턴스 종료3FEJT(MPCBM.BQ*OTUBODF.$MJFOUTDisconnectDelete(Client ID, Instance M)for all clientsExclude from routing targets
인스턴스 종료3FEJT(MPCBM.BQ*OTUBODF.$MJFOUTDisconnectDelete(Client ID, Instance M)for all clientsTerminateExclude from routing targets
O2O 서비스 특성 상 네트워크 연결이 불안정1. Client->Server 전송 실패2. Server->Client 전송 실패Fallback
O2O 서비스 특성 상 네트워크 연결이 불안정1. Client->Server 전송 실패->소켓 재연결 시도2. Server->Client 전송 실패Fallback
O2O 서비스 특성 상 네트워크 연결이 불안정1. Client->Server 전송 실패->소켓 재연결 시도2. Server->Client 전송 실패- 글로벌맵 조회 실패- 로컬맵 조회 실패- 소켓 메시지 전송 실패Fallback글로벌맵 조회로컬맵 조회소켓 메시지 전송
O2O 서비스 특성 상 네트워크 연결이 불안정1. Client->Server 전송 실패->소켓 재연결 시도2. Server->Client 전송 실패- 글로벌맵 조회 실패- 로컬맵 조회 실패- 소켓 메시지 전송 실패->GCM / APNS 푸시 메시지 전송Fallback글로벌맵 조회로컬맵 조회소켓 메시지 전송GCM / APNS푸시 메세지 전송실패실패실패
소켓 연결이 끊겼는데 글로벌맵, 로컬맵에서 제거되지 않은 경우1. 글로벌맵2. 로컬맵글로벌맵, 로컬맵 TTL(Time to live)
소켓 연결이 끊겼는데 글로벌맵, 로컬맵에서 제거되지 않은 경우1. 글로벌맵- 레디스 키-값 만료시간을 180초로 설정- 클라이언트-서버 메시지 전송이 있을 시 만료시간 갱신2. 로컬맵글로벌맵, 로컬맵 TTL(Time to live)
소켓 연결이 끊겼는데 글로벌맵, 로컬맵에서 제거되지 않은 경우1. 글로벌맵- 레디스 키-값 만료시간을 180초로 설정- 클라이언트-서버 메시지 전송이 있을 시 만료시간 갱신2. 로컬맵- 매 분마다 한 번씩 180초 이상 지난 키-값 제거 및 강제 연결 해제- 소켓 객체에 최근 클라이언트-서버 메시지 전송 시점 기록글로벌맵, 로컬맵 TTL(Time to live)
기술 스택
기술 스택Spring Boot Redis Pub/Sub
기술 스택Spring Boot Redis Pub/SubJava NIO Spring WebSocket Spring MVC
기술 스택Spring Boot Redis Pub/SubJava NIO Spring WebSocket Spring MVCKubernetesD2HUB(사내 Docker 이미지 저장소)
기술 스택Spring Boot Redis Pub/SubJava NIO Spring WebSocket Spring MVCKubernetesD2HUB(사내 Docker 이미지 저장소)Kibana 사내 APM Sentry
성능 테스트
30k+소켓 연결성능 테스트
7,00030k+소켓 연결 TPS성능 테스트
7,00030k+소켓 연결 TPS60%CPU,Memory,Thread Pool 사용률성능 테스트
성능 테스트6TFS$POOFDUJPO4FSWFS%SJWFS...6TFS %SJWFS nGrinder Agents
6TFS$POOFDUJPO4FSWFS30,000ConnectionsMessage1%SJWFS...6TFS %SJWFS Message15,000성능 테스트nGrinder Agents
성능 테스트nGrinder APM
신규 서버시작구 서버종료DNS 스위칭교체 완료서버 교체
성능 및 에러율
1ms >요청 처리 시간성능 및 에러율
6.09%1ms >요청 처리 시간 Fallback 비율성능 및 에러율
6.09%1ms >요청 처리 시간 Fallback 비율0%Fallback 실패율성능 및 에러율
인프라 비용21년 6월기존22년 6월신규
인프라 비용21년 6월기존22년 6월신규-65%
감사합니다