교환 재출고 송장이 덮어써지는 결함이 있었는데 이력을 뒤져 보니 2022년부터 4년간 같은 패턴으로 300회 넘게 시도됐고 최근에도 매달 몇 건씩 나고 있었다. 그동안 아무도 몰랐고 고객 문의가 유일한 발견 경로였다.
Table of contents
Open Table of contents
화면에 없는 실패 표시
실패한 건이 화면에서 어떻게 보이는지 확인하니 배송 준비 상태로 떠 있었고 실패가 노출되는 자리가 어디에도 없었다. 자동 재시도는 다섯 번쯤 돌다가 소진되면 완전히 멈추는데 멈춘 뒤에는 다시 시도하지도 않고 어디에 알리지도 않는다.
그래서 이 건은 두 조건을 동시에 만족한다. 실패했지만 실패로 표시되지 않고, 재시도가 멈춘 뒤 아무도 다시 보지 않는다. 이 둘이 겹치면 남는 발견 경로가 문의밖에 없다.
같은 형태의 사례들
상한이 경보를 막은 경우가 있었다. 한 번에 처리하는 건수에 상한을 뒀는데 상한에 도달한 분기가 연속 실패 카운터를 올리지 않아서, 신규 저장이 0건인 정체 상태가 이어져도 경보 조건이 성립하지 않았다.
헬스체크가 자기만 본 경우도 있었다. 서비스 주소를 바꾸면서 그 주소를 참조하는 다른 서비스의 설정을 안 고쳐 호출이 80분간 두절됐는데 컨테이너 헬스체크는 계속 정상을 반환했다. 헬스체크는 자기 기동 상태만 보지 대상 서비스 호출이 성공하는지는 보지 않는다.
지연 삭제가 미룬 경우와 로그가 성공으로 찍힌 경우도 있었다. 앞의 것은 참조 행을 즉시 지우고 실체는 큐에 넣어 화면이 아직 멀쩡한 상태였고, 뒤의 것은 패키지 제거가 의존성 때문에 실제로는 차단됐는데 로그에 제거 완료가 남은 경우였다.
공통점
넷 다 실패한 상태에서 실패 신호가 나오지 않는다는 점이 같고 그 이유는 조금씩 다르다. 실패 상태를 표시하는 자리가 없거나, 경보 조건이 그 실패 유형을 포함하지 않거나, 감시 대상이 실제 기능이 아니라 프로세스 생존이거나, 도구가 성공 문구를 남긴 경우다.
정상으로 보인다는 것이 정상이라는 뜻이 되려면 비정상일 때 다르게 보인다는 것이 먼저 확인돼야 한다. 넷 다 그 확인이 없던 자리였다.
감시 대상의 재정의
행위가 아니라 결과를 본다. 프로세스가 떠 있는지가 아니라 그 서비스로 요청이 실제로 흐르는지를 보고, 상태 확인 응답이 자기 자신만 보고 있으면 그것은 감시가 아니라고 본다.
재시도가 멈춘 뒤를 따로 본다. 재시도 중인 건은 언젠가 성공하거나 실패하지만 소진되고 멈춘 건은 아무 방향으로도 움직이지 않으므로 그 상태를 주기적으로 훑어야 한다.
진행이 0인 상태를 실패로 센다. 처리 완료가 0인데 시도만 계속되는 것은 정상이 아니고, 상한에 걸려 멈춘 것과 할 일이 없어 조용한 것을 구분한다. 미룬 것에는 표식을 남긴다. 지연 삭제나 나중 처리는 지금 정상인 것이 앞으로 정상이라는 뜻이 아니므로 소비 시점에 무엇이 깨지는지를 미리 확인하는 조건을 문에 건다.
발견 시점을 앞당긴 조회
앞의 송장 건에서는 문의가 들어오기 전에 하나를 찾았다. 재시도가 완전히 멈춘 채 며칠 방치된 건을 조회로 훑다가 나왔고, 마켓이 임의로 품절 처리하기 전이라 아직 개입할 수 있었다.
근본 수정과 별개로 소진 후 방치 건을 주기적으로 탐지하는 조회가 필요한 이유가 여기 있다. 근본 수정은 시간이 걸리고 그동안 발견 경로가 문의뿐이면 그 사이에 나는 건은 전부 사고가 된다.
정리
- 실패가 화면에 실패로 표시되지 않으면 발견 경로는 문의뿐이다
- 재시도 소진 후 방치된 건을 주기적으로 훑는다
- 상한에 걸린 분기가 실패 카운터를 안 올리면 정체가 조용해진다
- 헬스체크는 자기 기동만 보므로 서비스 간 호출로 검증한다
- 지연 처리는 깨짐을 막은 것이 아니라 미룬 것이다
- 도구가 남긴 성공 문구가 아니라 대상 상태를 다시 조회해 확인한다
- 정상으로 보이는 것이 정상이려면 비정상일 때 다르게 보여야 한다