요약

  • David Cheriton의 1988년 2월 RFC 1045는 원격 절차 호출 같은 요청·응답 거래를 위한 VMTP를 설명했다. Client, 32비트 Transaction 번호, 전달 횟수가 거래를 식별하고 서버 상태 기록이 중복 요청을 가려냈다.
  • 응답을 멱등으로 표시하면 분실 뒤 클라이언트가 요청을 다시 보내고 서버가 작업을 재수행해 새 응답을 만든다. 원래 결과를 보존해야 할 때는 복사본을 남기거나 확인까지 기다린다. 현재 시각은 다시 물어볼수록 오히려 최신 정보가 된다.

“한 번 더”라는 말에는 빠진 질문이 있다. 첫 번째 일이 이미 끝났는가? RFC 1045의 Versatile Message Transaction Protocol은 패킷을 잃을 수 있는 데이터그램 서비스 위에서 요청과 응답을 주고받도록 설계됐다. 원격 절차 호출이 대표적인 용도다. 서버는 일을 마쳤는데 답장만 사라졌을 수 있다. 두 번째 요청이 들어왔을 때 그 요청을 새 업무처럼 처리하면, 응답 한 장을 잃고 실제 일을 두 번 하게 된다.

VMTP는 업무표에 세 좌표를 적었다. 하나의 엔티티 도메인 안에서 Client, Transaction, ForwardCount가 거래를 식별한다. 32비트 Transaction 번호는 클라이언트 생성 시 무작위 값으로 시작해 보통 거래마다 늘어난다. 4비트 ForwardCount는 요청을 다른 서버로 넘길 때 쓰며 평소에는 0이다. 서버는 클라이언트별 상태 기록을 두고 같은 좌표의 요청을 중복으로 알아본다. 접수대가 “이 손님은 방금 다녀갔어요”라고 말할 수 있게 만든 셈이다.

접수대의 기억에도 보관 기간이 있다. 서버는 응답을 보낸 뒤 한동안 상태를 남겨, 늦게 도착한 요청 복사본을 막는다. 기록이 없을 때는 선택지가 세 가지다. Probe로 클라이언트 관리 모듈의 현재 거래 번호를 확인한다. 서버가 재시작하지 않았고 상태 보관 기간이 패킷 최대 수명과 재시도 시간을 덮었다면 새 요청으로 판단한다. 또는 안전하게 다시 할 수 있는 작업을 재수행한다. 클릭 한 번으로 보이는 재시도 뒤에는 네트워크의 시간과 서버의 기억을 따지는 회계가 있다.

멱등 응답이라면 VMTP는 서랍을 비운다. 옛 답을 저장하거나 그대로 재전송하지 않는다. 클라이언트가 Request를 다시 보내면 서버는 가장 최근 거래의 요청을 응용 프로그램에 다시 넘기고, 응용 프로그램이 작업을 재실행해 새 답을 쓴다. 더 오래된 늦은 요청은 버린다. Cheriton이 든 예가 현재 시각이다. 아까 적어 둔 시각을 찾는 것보다 지금 시계를 한 번 더 보는 편이 낫다. 열심히 보관한 기록이 오히려 정확도를 떨어뜨리는 드문 순간이다.

반대로 결과를 그대로 지켜야 하는 응답은 보관 비용을 치른다. VMTP 모듈은 응답을 실제로 복사하거나 쓰기 시 복사 방식으로 남긴다. 아니면 확인이 올 때까지 서버가 다음으로 넘어가지 못하게 한다. 메모리나 기다리는 시간이 비용이다. 시각 조회는 다시 해도 되지만, 장부를 바꾸는 작업은 한 번 더 수행되면 장부도 한 번 더 바뀐다. 어떤 창구를 선택할지는 패킷 크기가 아니라 응용 작업의 성질이 결정한다.

VMTP는 재전송 자체도 아꼈다. 손실이 드문 환경에서는 메시지 제어 블록만 먼저 다시 보내고, 상대가 필요한 데이터 조각을 골라 요청할 수 있다. 뒤따르는 요청은 프로토콜 기록에서 앞선 응답을 정리하는 역할도 한다. 저장 공간, 전송 바이트, 재실행 시간이라는 세 비용을 같은 장부에 적은 설계다. 한 칸에서 절약하면 다른 칸에 지출이 생긴다.

시계와 서랍을 고르는 장면은 우스꽝스럽지만, 재실행하면 안 되는 일을 시계 조회처럼 취급하면 웃을 수 없다. VMTP는 번호와 서버 상태로 낡은 요청을 가려냈다. 응용 프로그램은 자기 일이 반복 가능한지 알아야 했다. 이 RFC가 보여준 것은 “다시 시도”가 기술적 위로가 아니라 비용과 결과를 가르는 결정이라는 사실이다.