Skip to content
isdnetworks
Go back

한 곳뿐이던 메시지 중계

메시지 중계 서버가 재시작되면서 붙어 있던 서비스가 전부 멈췄다. 죽어 있던 시간은 사십 초 남짓이었는데 그동안 요청이 전부 실패했다.

Table of contents

Open Table of contents

한 대가 지고 있던 넷

서비스 넷이 그 중계 하나를 거치고 있었다. 그것이 멈추면 넷이 동시에 멈춘다.

재시작 자체는 몇십 초짜리 작업이었다. 그 몇십 초가 그대로 장애가 되는 구조가 문제였다.

붙는 쪽이 못 견뎠다

보내는 코드가 중계에 못 붙으면 예외를 그대로 올려서 요청이 실패했다. 중계가 잠깐 없다는 것과 요청이 실패해야 한다는 것은 별개인데 그 둘이 붙어 있었다.

못 붙으면 로컬에 쌓아 두고 복구되면 보내게 바꾸니 그 시간 동안 요청이 안 실패했다. 쌓는 양에 상한을 둔 것은 오래 죽어 있으면 그쪽 메모리가 차기 때문이다.

두 대로 늘린 뒤의 결정

중계를 두 대로 늘리고 붙는 쪽에 목록을 줘서 하나가 안 되면 다음을 시도하게 했다. 그러자 큐가 어느 대에 있고 한 대가 죽으면 그 큐는 어떻게 되는지를 정해야 했다.

복제하면 한 대가 죽어도 남지만 처리량이 준다. 전부 복제하지 않고 메시지 종류로 갈랐다.

잃어도 되는 것의 기준

어떤 메시지가 잃어도 되는지를 내가 판단할 문제가 아니었다. 물어보니 조회 로그는 통계에 쓰는 것이라 일부 빠져도 되지만 얼마나 빠지는지는 알아야 한다는 답이었다.

그래서 버린 것을 종류별로 세어 지표로 보내고 통계를 낼 때 그 숫자를 함께 보게 했다. 잃어도 된다는 말이 얼마가 빠져도 모른다는 뜻은 아니었다.

소비자 없는 큐

큐별 대기 건수를 보다가 한 큐에 소비자가 하나도 없는 것을 발견했다. 소비하는 서비스가 죽어 있었고 메시지는 계속 쌓이고 있었다.

중계 자체는 멀쩡하므로 중계만 보면 정상으로 보인다. 큐마다 소비자 수를 함께 보게 하고 0이면 알리게 했으며 중계가 멈췄을 때 무엇이 어떻게 되는지도 종류별로 적어 뒀다.

재시작 절차도 소비자를 먼저 멈추고 생산자가 로컬에 쌓게 한 뒤에 하는 순서로 바꿨다. 절차를 만들기 전에는 그냥 재시작했고 그것이 몇십 초의 장애가 됐다.

정리


Share this post on:

Previous Post
두 번 도착한 메시지
Next Post
다음 사람에게 남기는 것