TIL

다중 소켓서버 삽질 후기 (feat. 미친 20%)

하얀잔디 2025. 10. 13. 20:01

증상: 유저의 20%가 간헐적으로 소켓 연결 실패

 

처음엔 진짜 별거 아닌 줄 알았음.
전체 유저 중 한 20% 정도만 소켓 연결이 안 된다고 해서,
"아, 간헐적이면 당연히 클라 문제겠지" 하고 넘김.

근데 이상한 건,
개발 서버에서는 그런 현상이 단 한 번도 안 나타남.
그 순간부터 좀 찜찜했음.

 

 

의심 1차: Redis 클러스터 문제인가?

 

소켓 서버가 Redis Pub/Sub으로 메시지 주고받으니까
혹시 운영 Redis 클러스터링 문제인가? 싶었음.

그래서 클러스터 상태도 보고, cluster info 도 찍어봄.
결과는 정상.
slot 다 배정돼 있고, fail도 0.
Redis는 깨끗했음.

“그래, Redis는 무죄구나…”

 

 

의심 2차: 소켓 서버 로그 분석

 

그다음은 소켓 서버 로그를 보기로 함.
운영에 총 8개의 소켓 서버가 떠 있음.

하나씩 로그 열어보는데 이상한 게 있음.

  • 어떤 요청은 아예 소켓 로그가 좀 에러가 많아보였음.
  • 어떤 경우는 로그는 찍혔는데 실제로 통신이 안 됨.

이쯤 되니 “진짜 뭐지?” 싶음.
Docker 서비스는 다 살아 있고, health check도 통과인데
왜 이런 거지?

 

원인 추적: 특정 서버만 수상함

 

결국 8개 서버 중 하나하나 비교함.
그랬더니 특정 서버 한 놈이 이상함.

  • 접속 성공률 낮음
  • 로그 누락 많음
  • 그 서버에 붙은 유저들만 자주 끊김

이쯤 되니 거의 확신함.
“얘가 범인이다.”

 

원인: 특정 서버에서 Unhandled Rejection 터짐

결국 하나하나 서버 로그 grep 돌려서 분석함.
docker service logs -f uc_prd_socket | grep Unhandled

그랬더니 특정 서버 한 대에서만 주기적으로 Unhandled Rejection 에러가 터지고 있었음.

로그 예시 ↓

Unhandled Rejection at: Promise {...}, reason: TypeError: Cannot read properties of undefined

 

이게 문제였음.
비동기 함수 안에서 try-catch가 누락된 부분이 있었고,
그게 내부 Promise 체인에서 터지면 프로세스가 잠깐 멈추거나,
이벤트 루프가 꼬여서 새로운 소켓 연결이 제대로 처리되지 않음.