Skip to content
isdnetworks
Go back

한 레이어만 보면 답이 안 나온다

(수정됨)

주문을 취소했는데 외부 거래소의 헤지 주문은 안 취소됐다는 문의를 받았다. orders 를 보니 status = 'CANCELED' 라 우리 쪽은 정상으로 보였다.

Table of contents

Open Table of contents

증상 — 정상으로 보이던 내부 상태

이 시스템은 내부 상태를 담는 orders 층과 외부 거래소와 주고받은 기록을 담는 hedge_sync_log 층으로 나뉘어 있었다. 내부 상태는 회원이 취소를 누른 시점에 바뀌고 외부 전송은 그 뒤에 ActiveMQ 를 거쳐 일어난다.

hedge_sync_log 를 조회하니 전송이 FAILED 인 채로 멈춰 있었다. 우리 쪽은 취소 완료이고 외부에는 안 간 어긋난 상태였다.

원인 — 한쪽만 보면 반대 결론이 난다

orders 만 보면 정상이고 hedge_sync_log 만 보면 실패다. 한쪽만 보고 답하면 어느 쪽을 봤느냐에 따라 정반대 결론이 나오고 둘 다 근거가 있어 보인다.

문의를 받고 orders 만 조회한 채로 정상이라고 답할 뻔했다. 두 층을 함께 봐야 내부는 됐고 외부는 안 됐다는 사실이 나온다.

판단 기준 — 지연과 누락의 구분

같은 조사에서 본 다른 건은 hedge_sync_log 자체가 없었다. 체결 통보 수집 배치가 아직 안 돈 것이었고 몇 시간 뒤에 확인하니 기록이 생기고 DONE 으로 완료돼 있었다.

기록이 없다는 관측이 누락일 수도 지연일 수도 있으므로 그 둘을 갈라야 했다. 회신하기 전에 한 번 더 조회하니 답이 완료됐다는 내용으로 바뀌었다.

비슷한 두 건을 나란히 놓기

이 조사가 수월했던 것은 두 건의 조건이 거의 같았기 때문이다. 마켓과 status 와 수량과 updated_at 이 같고 갈린 것이 연동 층뿐이었다.

조건이 달랐으면 무엇 때문에 갈렸는지 알 수 없다. 비슷한 두 건을 나란히 놓는 것이 이런 조사의 절반이었다.

조치 — 당장 조치와 근본 대응

당장 조치는 재전송이었다. 두 가지 방법이 있었다. 관리 화면에서 POST /hedge/{id}/resend 를 손으로 누르는 것과, FAILED 건을 retry_count 상한까지 자동으로 다시 보내는 잡을 두는 것이다. 뒤쪽을 골랐다. 이유는 손으로 누르는 것은 문의가 온 건만 고치고 안 온 건은 그대로 남기기 때문이다. 대신 상대 거래소가 이미 처리한 취소를 두 번 보내는 경우가 생겨 client_order_id 로 멱등하게 만들어야 하는 것을 감수했다.

그것만으로는 다음에 또 생긴다. 수집 배치의 지연 한계와 FAILED 가 오래 지속될 때의 알림을 따로 적었는데, 셋째가 없어서 이틀 가까이 오류 상태였는데 아무도 몰랐다. 당장 조치와 근본 대응을 나눠 적으면 급한 것을 처리하면서도 다음 것을 놓치지 않는다.

정리


Share this post on:

Previous Post
느린 것이 아니라 줄 선 것
Next Post
그 NULL이 정말 이상한가