현상
느린 회선(초당 5~6KB)을 쓰는 한 노드가 14.7MB 설치본을 1.5시간 동안 15번 시도했는데, 매번 0바이트부터 다시 받고 최대 3.6MB에서 끊겼다. 15번 중 6번은 nginx의 send_timeout(60초)에 걸렸고, 9번은 노드·회선 쪽에서 연결이 닫혔다.
원인은 다운로드 함수(RequestFile)가 전송 중간에 끊겨도 true를 돌려준다는 데 있었다. 잘린 파일은 해시 검증에서 떨어졌고, 남는 기록은 「AGENT UPDATE FAILED」뿐이라 왜 실패했는지 알 수 없었다.
원칙
- 이어받기로 근본 해결한다.
- 시간 제한을 두지 않는다. 진척이 있는 동안은 계속 시도한다.
- 실패 이유는
agent.error.log에 한 줄 남긴다.
설계
YAgent::DownloadFileResume(common/Http.cpp, WinINet 기반)으로 구현했다.
- 다운로드 중인 파일은
<경로>.part와<경로>.part.info(URL·ETag 저장) 두 개로 관리한다. - 이어받을 때는
Range헤더와If-Range(강한 ETag)를 함께 보낸다. - 서버 응답이
206이면Content-Range를 엄격히 맞춰서 기존.part에 이어 붙인다. 200이 오면(서버가 Range를 무시했다는 뜻).part를 비우고 새 ETag를 적은 뒤 처음부터 받는다.416(bytes */전체)이고 그 전체 크기가 이미 받아 둔 크기와 같으면 그걸로 마무리한다.- 받은 크기가 전체 크기와 같을 때만 최종 경로로 옮기고, 기존 해시·서명 검증을 그대로 거친다. 검증에 실패하면 파일을 삭제해 다음 시도는 처음부터 받게 한다.
남은 일
- 빌드 뒤 느린 회선 가상 머신에서 QA 시험을 한다.
- 서버 쪽
send_timeout조정은 별도로 완료했다.
Orange Platform 에이전트 업데이트 다운로드 안정화 작업 정리입니다.