헤지용 외부 거래소 계정이 잘못 연결됐다는 요청을 받고 markets → exchange_accounts → api_credentials 체인을 따라가 계정을 고쳤다. 조회하면 체인은 새 계정을 가리키는데 인증은 여전히 401 로 실패했다.
Table of contents
Open Table of contents
증상 — 고친 체인과 어긋난 결과
체인을 JOIN 해서 확인하니 새 api_key 를 정확히 가리키고 있었다. 그런데 hedge_sync_log 에는 옛 계정의 api_key 앞자리가 찍히고 있었다.
보이는 연결과 실제로 쓰이는 연결이 다르다는 뜻이다. 그러면 읽는 쪽이 다른 곳을 보고 있다고 봐야 한다.
원인 — 관계 테이블이 먼저였다
HedgeClientFactory 를 따라가니 별도 관계 테이블 market_credential_overrides 를 먼저 조회하고 있었다. 거기에 행이 있으면 그것을 쓰고 없을 때만 체인으로 내려가는 구조였다.
오버라이드 테이블에는 옛 계정을 가리키는 행이 남아 있었고 체인을 고쳐도 그 행은 바뀌지 않는다. 내가 정본이라고 생각한 체인이 실제로는 폴백이었다.
판단 기준 — 우선순위가 반대인 구조
이 구조에서는 반대 경우도 성립한다. 오버라이드가 정상이면 체인이 어긋나 있어도 실질 장애가 나지 않는다.
그래서 체인만 보고 정상이라고 말할 수 없고 이상이라고도 말할 수 없다. 두 가지 방법이 있었다. 오버라이드 테이블을 없애고 체인 하나로 통일하는 것과, 점검 순서를 오버라이드부터 보고 없으면 체인을 보고 둘 다 보정하는 것으로 정하는 것이다. 뒤쪽을 골랐다. 이유는 오버라이드가 특정 마켓만 다른 계정으로 헤지하려는 운영 요구로 만들어진 것이라 없앨 수 없어서다. 대신 점검 절차가 두 단계로 갈리는 것을 감수했다.
식별자 어긋남이 만든 부분 실패
같은 조사에서 계정별 API 키와 상대 쪽 uid 가 어긋난 경우도 나왔다. 이 경우 주문 등록은 되는데 조회와 취소가 실패한다.
전부 실패하면 연결을 의심하는데 일부가 되면 연결은 맞다고 보고 다른 원인을 찾게 된다. 부분 실패가 진단이 어려운 것은 되는 것이 있다는 사실이 잘못된 결론을 지지하기 때문이다.
주의 — 폴백이 감추는 것
확인은 양방향으로 하기로 했다. 상대의 uid 가 어느 API 키의 것인지 보고 연결된 계정이 그 키를 쓰는지도 본다.
한 방향만 보면 연결돼 있다는 것까지만 알 수 있다. 폴백 구조는 결과만 봐서는 어느 경로를 탔는지 감추므로 오버라이드 행의 유무가 디버깅의 첫 질문이 된다.
정리
- 별도
market_credential_overrides가 체인보다 우선할 수 있다 - 체인을 고쳐도 오버라이드가 옛것을 가리키면 그대로 나간다
- 오버라이드가 정상이면 체인이 어긋나도 실질 장애가 없다
- 그래서 체인만 보고 정상이라고도 이상이라고도 말할 수 없다
- 점검은 오버라이드부터 보고 없을 때 체인을 보며 둘 다 보정한다
uid가 어긋나면 등록은 되고 조회와 취소가 실패한다- 부분 실패는 되는 것이 있어 잘못된 결론을 지지한다
- 폴백은 어느 경로를 탔는지 감추므로 조건부터 확인한다