장애 주입 시험으로, 런타임이 잠시 멈추면 정리를 포기하고 자리가 이중 배정되는 결함을 찾아 고쳤다
- 장애 뒤 남은 컨테이너 100 → 0개
- 돌연변이 12/12 검출
문제 상황
앞선 부하 시험은 모든 요청이 성공하는 경우만 봤다. 대회 중 런타임이 잠시 응답하지 못할 때 문제 서버와 자원 예약이 새는지는 아무도 확인하지 않았다. 가짜 런타임에 장애를 주입해 보니, 삭제 접수가 5번 연속 실패하면(약 100초) 인스턴스를 FAILED로 옮기고 예약을 반납하는 경로가 있었다. FAILED는 워커가 다시 보지 않아 컨테이너가 남는데, 브로커는 그 자리를 비었다고 보고 다른 팀에 다시 배정한다.
해결 방안
재시도 한도를 포기하는 기준이 아니라 경보 기준으로만 쓰기로 했다. 런타임이 지워졌다고 확인해 줄 때만 정리를 끝내고, 그 밖의 실패는 상태와 예약을 쥔 채 재시도한다. 장애가 길어지면 새 요청을 받을 자리가 줄지만, 사용 중인 자리를 다시 배정하는 것보다 낫다고 봤다. 같은 정리 경로를 다른 설계로 고친 팀원의 초안(확정 실패는 운영자에게 넘기기)과 충돌했다. 런타임 소스를 읽어 같은 요청 id의 재접수는 다시 실행되지 않는다는 것을 확인하고, 런타임이 확정한 실패는 운영자 재시도로, 일시적인 실패는 자동 재시도로 나눠 두 설계를 합쳤다.
결과
로컬에서 가짜 브로커와 런타임으로 100건을 만든 뒤 런타임 전체 장애를 150초 걸었다. 고치기 전에는 약 40초 만에 100건이 FAILED가 되고 컨테이너 100개가 남았다. 고친 뒤에는 장애 내내 삭제 진행 중으로 남았다가, 복구 뒤 40초 안에 100건이 모두 정리되고 남은 컨테이너와 예약이 0이 됐다. 같은 틀로 강제 재시작과 만료 몰림(각 300건), 약 1시간 49분 동안 1,520건을 도는 장시간 시험도 돌려 남은 컨테이너 0을 확인했다. 전체 테스트 655건이 통과했고, 판정 로직을 일부러 바꾼 코드 12개를 모두 테스트가 잡았다.
