주문 취소가 외부 거래소 쪽에 전송되지 않았다는 보고를 받고 hedge_sync_log 를 조회하니 FAILED 가 남아 있었다. 보고 시각과 실패 시각이 거의 같았다.
Table of contents
Open Table of contents
증상 — 실패 기록과 보고 시각
실패 기록이 있고 시각도 맞으니 그대로 장애로 판단할 수 있는 상황이었다. 보고 내용과 기록이 일치하면 더 볼 필요가 없어 보인다.
그런데 그 기록이 마지막 상태인지는 확인한 것이 아니었다. 같은 order_id 에 다른 기록이 더 있는지를 보기로 했다.
검증 — 뒤를 더 보니 성공이 있었다
같은 order_id 로 범위를 넓혀 ORDER BY created_at 으로 조회하니 두 시간쯤 뒤에 DONE 기록이 있었다. 앞서 넣어 둔 재시도 잡이 자동으로 다시 보냈고 두 번째에 성공했다.
보고자는 실패한 순간을 목격한 것이고 그 뒤에 복구되는 것은 보지 못했다. 조사 시점에는 이미 정상이었다.
원인 — 재시도가 새 행을 만드는 구조
기록 구조를 보니 재시도할 때 기존 행을 UPDATE 하지 않고 attempt 를 올린 새 행을 INSERT 하고 있었다. 같은 대상에 FAILED 행과 DONE 행이 함께 남는다.
이력이 남는 장점이 있는 대신 최신 상태를 알려면 정렬해서 마지막을 봐야 한다. 첫 행만 보고 결론 낸 것이 처음 판단이 틀린 이유였다.
판단 기준 — 복구되는 것과 보이는 것
이 건은 조치 없이 해결됐지만 좋기만 한 것은 아니었다. 실패와 복구 사이 두 시간 동안 운영자도 몰랐고 회원은 안 됐다고 느꼈다.
자동으로 복구되는 것과 그 구간이 보이는 것은 별개의 문제였다. 두 가지 방법이 있었다. 재시도 간격을 줄여 구간 자체를 짧게 만드는 것과, 진행 상태를 화면에 표시하고 복구까지 걸린 시간을 Micrometer 지표로 남기는 것이다. 뒤쪽을 골랐다. 이유는 간격을 줄이면 상대 거래소의 429 를 더 자주 맞아서다. 대신 화면에 「전송 재시도 중」 상태를 하나 더 만들어야 하는 것을 감수했다.
회신에 함께 적을 것
이미 정상 처리됐다고만 회신하면 보고자는 자기가 잘못 본 것으로 여긴다. 그러면 다음에 진짜 문제가 있어도 보고하지 않게 된다.
확인 시점에는 FAILED 상태였고 재시도로 정상 처리됐다는 사실과 그 사이에 상태가 표시되지 않는 문제가 있다는 것을 함께 적었다. 보고가 맞았다는 것과 남는 문제를 나란히 두는 것이 회신의 형태가 됐다.
정리
- 실패 기록을 봤으면 그것이 마지막 상태인지 확인한다
- 자동 재시도로 이미 복구됐을 수 있다
- 재시도가 새 행을
INSERT하는 구조면 최신순으로 전부 본다 - 첫 행만 보고 결론 내지 않는다
- 자동 복구되는 것과 그 구간이 보이는 것은 별개다
- 진행 상태를 표시하고 복구 소요 시간을 지표로 남긴다
- 평소 값을 알아야 이번 것이 이상한지 판단된다
- 회신에 보고가 맞았다는 것과 남는 문제를 함께 적는다