요약

  • RFC 2188의 확인 응답 결과 모드는 호출자가 이미 그 결과를 수신하고 수용했을 수 있음에도, 수행자가 성공 결과를 보낸 후 실패를 보고하도록 의도적으로 허용했습니다. 따라서 두 엔드포인트는 서로 다르지만 각자 성실한 근거를 가진 채 마무리될 수 있었습니다.
  • ESRO는 호출, 실행, 결과 생성, 결과 전달, 확인 응답, 로컬 확인을 분리했습니다. Invoke ID는 교환을 상호 연관시켰지만, 상대를 인증하거나 작업을 멱등으로 만들거나 지속적인 비즈니스 완료를 증명하지는 않았습니다.
  • 이 프로토콜의 두 핸드셰이크 모드는 정보와 오버헤드를 맞바꿨습니다. 확인 응답 결과는 ACK를 통해 수행자에게 상대로부터 파생된 근거를 제공했고, 비확인 응답 결과는 그 지식 없이 로컬에서 끝났습니다.
  • RFC 2188은 1997년 9월에 Informational RFC로 공개되었으며 Internet Standard가 아니었습니다. 상태 기록에는 IETF 작업 그룹 검토를 거치지 않았다는 사실과 IESG의 확장성 우려가 함께 남겨져 있었습니다.
  • 운영상의 교훩은 좁지만 중요합니다. 타임아웃, 재전송 한도 초과, 로컬 실패 표시는 특정 프로토콜 관찰에 대한 근거일 뿐, 다른 엔드포인트가 무엇을 실행했고 수신했으며 커밋했고 이후 조정했는지에 대한 보편적 진술이 아닙니다.

성공으로 끝나는 실패

먼저 수행자를 상상해 보십시오.

수행자는 호출을 받아 요청된 작업을 수행하고 성공 결과를 생성합니다. 그 결과를 호출자 쪽으로 보냅니다. 반대편에서 호출자는 그것을 받아 작업이 성공적으로 수행되었다고 처리합니다. 호출자의 관점에서 교환은 필요한 것을 전달했습니다.

그러나 수행자는 아직 같은 결론을 내릴 자격이 반드시 생기지 않습니다.

ESRO의 3방향 확인 응답 결과 모드에서 수행자는 결과나 오류를 보낸 뒤 ACK를 기다립니다. 수행자의 로컬RESULT.confirm또는ERROR.confirm은 그 ACK를 수신한 후에 발생합니다. 확인 응답이 도착하지 않으면 설정된 한도가 소진될 때까지 재전송이 계속될 수 있고, 수행자는FAILURE.indication을 받을 수 있습니다.

언뜻 모순처럼 들립니다. 실제로 작업이 성공했다면 수행자가 어떻게 실패를 보고할 수 있을까요?

그 이유는 이 실패가 원격 작업 전체에 대한 소급적 판정이 아니기 때문입니다. 그것은 수행자 쪽 프로토콜 기계가 무엇을 확립할 수 있었는지에 대한 진술입니다.

결과 PDU가 유실되었을 수 있습니다. 또는 결과는 도착했지만 호출자의 ACK가 되돌아가는 경로에서 유실되었을 수도 있습니다. 혹은 로컬 ESRO 공급자 자체가 실패했을 수도 있습니다. 이 경우들은 서로 다른 원격 현실을 만들면서, 수행자에게는 같은 로컬 실패 표시로 수렴할 수 있는 근거를 제시합니다.

바로 이 구분이 RFC 2188의 중심입니다.

수행자 측 실패는 호출자가 성공적 결과를 받지 못했다는 것을 견고하게 증명하지 못합니다. 따라서 RFC는 가능한 대응책 중 하나로, 애플리케이션이 실제 무슨 일이 있었는지 알아야 할 때 별도의 검증 작업을 사용하는 것을 제시합니다.

핵심은 ESRO가 상태 관리에 부주의했다는 것이 아닙니다. 오히려 그 반대에 가깝습니다. 이 명세는 누구의 상태가, 어느 단계에서, 어떤 근거로 알려지는지를 이례적으로 명시적으로 다루기 때문에 가치가 있습니다.

작게 설계된 프로토콜

RFC 2188은 Efficient Short Remote Operations, 즉 ESRO를 UDP 위의 신뢰할 수 있는 커넥션리스 원격 작업을 위한 저오버헤드 프로토콜로 규정했습니다. 이 설계는 프로토콜 오버헤드가 중요한 링크, 특히 CDPD 같은 무선 환경에 특별한 주의를 기울였습니다.

ESRO는 요청 하나와 응답 하나를 주고받는 데 그치지 않았습니다. 세그먼테이션과 재조립, 연결과 분리, 애플리케이션 멀티플렉싱 기능을 포함했습니다. 또한 모든 작업이 동일한 확인 의미를 필요로 한다고 가정하는 대신, 서로 다른 두 가지 결과 처리 모드를 제공했습니다.

UDP 서비스는 포트 259를 사용했습니다.

이 프로토콜은 1997년 9월에 Informational RFC로 등장했습니다. Internet Standard가 아니었습니다. RFC의 상태 자료는 IETF 작업 그룹 검토를 받지 않았다고 밝히면서, IESG는 확장성에 대한 경고를 붙였습니다. 이 세부 사항이 중요한 이유는 읽고 있는 문서의 성격을 정의하기 때문입니다. 명시적으로 문서화된 프로토콜 제안과 운영 설계이지, 그 아키텍처가 보편적 인터넷 관행을 대표한다는 주장이 아닙니다.

훗날 RFC 2524는 ESRO를 효율적인 메일 전송 및 전달의 기반으로 사용했습니다. 이 후속 계층화는 이 메커니즘의 의도된 응용을 보여줍니다. 그러나 이것이 현재의 배포, 상업적 보급, 보편적 운영 성공을 확립하지는 않습니다.

호출자와 수행자는 같은 시점을 점하지 않는다

ESRO는 두 역할을 이름 붙입니다. 호출자(invoker)와 수행자(performer)입니다.

이 어휘는 실질적인 역할을 합니다. 원격 작업을 마치 어디에도 없는 단일 관찰자가 지켜보는 것처럼 서술하지 못하게 막아 줍니다.

호출자는 작업을 요청합니다. 수행자는 요청을 받아 작업을 시도합니다. 수행자는 이후 성공적 수행을ESROS-RESULT로, 실패한 수행을ESROS-ERROR로 보고할 수 있습니다.

이 서비스 프리미티브들은 수행된 작업에 관한 것입니다. 이후의 확인과 실패는 별개의 근거 계층에 속합니다.

이 구분은 쉽게 흐려집니다. 성공적 결과는 수행자의 실행에 관해 말합니다. 그 결과의 전달은 또 다른 것에 관해 말합니다. 호출자 표시는 호출자 측 ESRO 서비스가 해당 프로토콜 이벤트를 관찰했다는 뜻입니다. 확인 응답 모드의 ACK는 또 하나의 사실을 더합니다. 수행자가 호출자 쪽에서 거슬러 올라오는 상대 파생 확인을 받았다는 사실입니다.

이 어느 사실도 인증, 멱등성, 지속적 애플리케이션 커밋, 이후의 조정과 동일하지 않습니다.

교환을 하나의 이원적 거래가 아니라 근거 경계의 연속으로 읽으면 RFC 2188이 더 명확해집니다.

  1. 호출 요청이 존재한다;
  2. 호출이 전달된다;
  3. 수행자가 요청된 작업을 실행하거나 거절한다;
  4. 결과 또는 오류가 생성된다;
  5. 그 결과 또는 오류가 전달되거나, 그렇지 않다;
  6. 호출자가 해당 표시를 수신한다;
  7. 확인 응답 모드에서는 ACK가 되돌아온다;
  8. 각 엔드포인트가 자신의 로컬 confirm 또는 failure 이벤트를 만든다;
  9. 인증이 있다면 ESRO 밖에서 처리된다;
  10. 반복 요청을 어떻게 식별할지는 애플리케이션이 결정한다;
  11. 지속적인 비즈니스 상태가 관련된다면 다른 곳에서 커밋된다;
  12. 불일치는 나중에 조정될 수 있다.

이후 계층은 앞선 계층에 의존할 수 있지만, 앞선 계층이 일어났다는 이유만으로 증명되지는 않습니다.

세 개의 메시지는 더 많은 지식을 산다

확인 응답 결과 모드는 3방향 교환을 사용합니다.

수행자가 결과나 오류를 보냅니다. 호출자가 그것을 받고 ACK를 보냅니다. 수행자가 그 확인 응답을 받으면RESULT.confirm또는ERROR.confirm을 생성할 수 있습니다.

그 마지막 단계가 수행자에게 상대로부터 파생된 정보를 제공합니다.

ACK는 호출자를 인증하지 않습니다. 외부 데이터베이스 트랜잭션이 지속적임을 보여 주지도 않습니다. 하위 물리적 동작이 일어났다고 말하지도 않습니다. 정확히 한 번의 실행을 만들어 내지도 않습니다.

그것이 하는 일은 더 좁습니다. 수행자가 프로토콜 교환에 대해 알 수 있는 것을 바꾼다는 것입니다.

패킷이 사라질 때 이 비대칭이 특히 두드러집니다. 성공적 결과는 호출자에 도달했지만 ACK가 되돌아오지 못했다고 가정해 보십시오. 호출자는 성공 표시를 가질 수 있는 반면, 수행자는 결국 재전송을 다 소진하고 실패를 기록합니다. 두 엔드포인트의 관찰을 하나의 전역 상태에 대한 선언으로 잘못 취급할 때만 불일치가 됩니다. 프로토콜 수준에서는 그들의 로컬 근거가 단순히 다를 뿐입니다.

RFC 2188은 반대 경우의 방향성 함의도 밝힙니다. 확인 응답 모드에서는 호출자 측 실패가 수행자 실패를 함의합니다. 그래도 두 엔드포인트의 관찰이 일반적으로 호환 가능해지는 것은 아닙니다. 명세는 특정 이벤트들 사이의 특정 관계를 정의할 뿐, 두 엔드포인트를 하나의 공유 오라클로 축소하지 않습니다.

두 개의 메시지는 의도적으로 덜 산다

비확인 응답 결과 모드는 세 번째 메시지를 제거합니다.

여기서 수행자의RESULT.confirm과ERROR.confirm은 상대로부터의 정보 없이 생성됩니다. 따라서 그 의미는 로컬입니다. 이것들은 작업의 수행자 측 종료를 표시할 뿐, 호출자가 결과나 오류를 받았다는 것을 확립하지 않습니다.

이 차이는 외관이 아니라 아키텍처의 차이입니다.

이 모드에서는 프로토콜이 수행자의FAILURE.indication을 생성하지 않습니다. 같은 수행자 측 실패 경로를 뒷받침할 수 있는 기다려진 ACK가 존재하지 않기 때문입니다. 수행자는 호출자의 수신 상태를 알지 못한 채 로컬에서 마무리될 수 있습니다.

호출자는 여전히 실패할 수 있습니다. 호출자 측 실패는 결과, 오류, 실패 중 아무것도 도착하지 않았다는 뜻이거나, 로컬 호출자 공급자의 실패가 발생했다는 뜻일 수 있습니다.

다시 한 번, 여러 가능한 역사가 같은 로컬 관찰에 사상될 수 있습니다.

따라서 2방향 모드는 원격 확실성을 더 싸게 만들지 않습니다. 그 확실성 중 일부를 얻지 않기로 선택합니다.

저오버헤드 프로토콜이 내릴 수 있는 정확히 그런 절충입니다. 메시지 하나를 줄이는 것은 바이트와 지연을 줄이는 것만이 아니라, 생략된 메시지가 제공했을 근거까지 제거합니다.

상관관계는 동일성이 아니고, 동일성도 커밋이 아니다

ESRO는 프로토콜 활동을 연관 짓기 위해 invoke ID를 사용합니다.

그것은 유용하지만, 역할이 너무 느슨하게 서술되면 상관관계가 실제로 갖지 못한 능력을 끌어당길 수 있습니다.

invoke ID는 상대를 인증하지 않습니다. RFC 2188은 인증을 ESRO 밖에 두고, 수행자 인증의 책임을 프로토콜 자체를 넘어서는 메커니즘에 부과합니다.

invoke ID는 작업을 멱등으로 만들지도 않습니다. 요청이 되돌릴 수 없거나 반복 불가능한 부작용을 일으킨다면, 두 메시지를 관련된 것으로 식별하는 것만으로는 그 부작용이 한 번만 발생한다는 보장이 되지 않습니다.

그리고 invoke ID는 비즈니스 커밋을 증명하지 않습니다. 프로토콜은 호출과 그 결과를 연관시킬 수 있지만, 애플리케이션은 여전히 자체적인 영속성, 인가, 조정 규칙을 가집니다.

같은 원칙이 매개변수 인코딩에도 적용됩니다. RFC 2188은 인코딩 유형에 대한 정보를 실어 보내거나 태그할 수 있지만, 매개변수 자체의 의미적 정의는 프로토콜의 범위 밖입니다.

이 경계가 중요한 이유는 인코딩 구문과 애플리케이션 의미가 서로 다른 설계 계층이기 때문입니다. 프로토콜은 애플리케이션이 거부하는 의미를 지닌 인코딩된 매개변수, 요청된 동작이 다르게 인가되는 매개변수, 궁극적 부작용에 다른 일관성 메커니즘이 필요한 매개변수를 성공적으로 전달할 수 있습니다.

신뢰성은 배포 선택에 부분적으로 좌우된다

ESRO는 프로토콜 기계를 규정하지만 배포 판단을 없애지는 않습니다.

구현과 배포는 재전송 간격, 최대 재전송 횟수, 비활성 시간, 참조 번호 수명과 함께 작업해야 합니다. 이 값들은 ESRO가 작동할 것으로 예상되는 네트워크에 맞춰 선택됩니다.

그렇다는 것은 신뢰성이 프로토콜 이름으로 환원되지 않는다는 뜻입니다.

어떤 지연·손실 환경에 맞는 재전송 정책은 다른 환경에서는 형편없이 작동할 수 있습니다. 실제 네트워크와 재시도 행동에 비해 너무 짧은 참조 번호 수명은 상관관계 위험을 만들 수 있습니다. 긴 비활성 간격은 필요 이상으로 상태를 오래 유지할 수 있고, 짧은 간격은 지연된 트래픽이 도착을 마치기 전에 상태를 만료시킬 수 있습니다.

따라서 이 RFC는 정확성이 패킷 형식뿐 아니라 상태 머신 가정과 사용 중인 네트워크 사이의 관계에 달려 있는 부류의 프로토콜에 속합니다.

설계는 전송 계층에서 커넥션리스로 남습니다. ESRO는 UDP 위에서 실행되는데, UDP의 기본 서비스 자체는 신뢰할 수 있는 원격 작업 추상을 만들지 않습니다. ESRO는 그 기반 위에 자체적인 작업 지향 신뢰성 메커니즘을 구축합니다.

축소판 RPC 역사가 아니다

ESRO를 원격 프로시저 호출 일반에 관한 우화로 만드는 것은 유혹적입니다.

그러나 그것은 너무 광범위합니다.

ONC RPC를 기술한 RFC 1831은 원격 호출 메커니즘의 더 넓은 역사에 속하지만, RFC 2188은 자체적인 프리미티브, 역할, 실패 의미를 지닌 독자적 설계입니다. 여기서 그 의의는 모든 RPC 시스템을 대표하게 만드는 것이 아니라, 그 의미들의 구체성에 있습니다.

마찬가지로 ESRO를 일반적인 “정확히 한 번” 주장에 관한 논쟁에 끌어들여서는 안 됩니다.

이 RFC는 invoke ID, 재전송, 확인 응답을 갖고 있다는 이유만으로 그 추상을 부여하지 않습니다. 재전송은 중복 프로토콜 트래픽을 가능하게 할 수 있습니다. 중복 호출 상황에서의 애플리케이션 행동은 별개의 문제입니다. 프로토콜 수준의 성공만으로는 외부의, 지속적인, 멱등하지 않은 동작이 정확히 한 번 일어났다는 것이 증명되지 않습니다.

또한 이것이 현대 분산 트랜잭션 프로토콜의 1997년 버전도 아닙니다. ESRO ACK를 여러 시스템에 걸친 트랜잭션 커밋 기록과 동등하게 다룰 근거는 없습니다.

유용한 역사는 더 작고 더 정확합니다. RFC 2188은 단일 작업(short-operation) 프로토콜 안에서 효율성 선택과 엔드포인트 상대적 지식을 명시적으로 모델링했습니다.

각 이벤트가 실제로 뒷받침할 수 있는 것

ESRO에 대한 근거 있는 읽기는 로컬 이벤트를 보편적 사실로 승격시키려는 유혹을 거부합니다.

호출 요청은 호출이 발행되었다는 것을 증명하며, 도착했다는 것은 증명하지 않습니다.

수행자에게의 전달은 수신을 증명하며, 성공적 실행을 증명하지 않습니다.

ESROS-RESULT는 성공적으로 수행된 작업을 나타내지만, 이후 전달은 여전히 실패할 수 있습니다.

호출자 결과 표시는 호출자 측 프로토콜이 결과를 관찰했다는 것을 증명하며, 독립적인 비즈니스 원장이 지속적으로 갱신되었다는 것을 증명하지 않습니다.

확인 응답 모드의 ACK는 프로토콜 교환에 관해 상대로부터 파생된 추가 근거를 수행자에게 주지만, 인증이나 멱등성은 주지 않습니다.

결과 전송 이후의 수행자FAILURE.indication은, 호출자가 이미 성공적 결과를 받았던 역사를 포함하여 여러 역사와 양립할 수 있습니다.

타임아웃은 타이머가 만료되었다는 것을 증명합니다.

이 마지막 문장은 거의 시비 같게 들립니다. 그러나 이것이야말로 문제의 운영적 핵심입니다.

“타임아웃”을 “원격 동작이 일어나지 않았다”로 바꾸는 것은 타이머 자체가 확립할 수 없는 주장을 추가합니다.

검증은 불확실성에 대한 프로토콜 수준의 인정이다

RFC 2188이 별도의 검증 작업을 제안한 점은 시사적입니다.

이 제안은 확인 응답 교환이 수행자 측 불확실성으로 끝난 뒤에도, 맹목적 반복이 유일한 가능한 대응은 아니라는 것을 인정합니다. 애플리케이션은 다른 질문을 던질 수 있습니다. 지금 상태는 무엇인가?

이는 회복 전략을 추론 시도에서 명시적 관찰로 바꿉니다.

이 구분은 작업이 안전하게 반복 가능하지 않을 때 결정적으로 중요해집니다. 원격 요청이 “이 상태를 돌려줘”를 의미한다면 반복은 비용이 낮을 수 있습니다. 반대로 “중복을 단순히 되돌릴 수 없는 외부 동작을 수행해라”를 의미한다면, 모호한 타임아웃 뒤의 재시도가 위험한 선택일 수 있습니다.

검증 작업이 모든 불확실성을 마법처럼 없애 주지는 않습니다. 그 자체의 요청과 응답도 분산 시스템을 통과합니다. 그러나 검증은 애플리케이션이 불확실성을 확실성으로 위장하지 않고 정직하게 표현할 방법을 줍니다.

그것이 개별 오피코드보다 더, RFC 2188의 지적으로 오래가는 특징입니다.

효율성과 지식은 명시적으로 맞바뀌었다

ESRO는 짧은 신뢰성 작업을 효율적으로 만들도록 설계되었습니다. 따라서 프로토콜은 메시지 비용을 가시적으로 만들었습니다.

3방향 모드는 수행자 측 추가 지식을 얻기 위해 확인 응답 하나를 소비합니다. 2방향 모드는 그 교환을 피하고 더 로컬적인 완료 개념을 받아들입니다.

이것은 단순한 “안전 모드 대 불안전 모드”가 아닙니다. 둘 다 정의된 의미를 갖습니다. 중요한 질문은 애플리케이션이 어떤 근거를 필요로 하는가입니다.

상대 파생 지식이 중요한 곳에서는 ACK에 가치가 있습니다.

수행자가 자신의 결과 처리 경로가 끝났다는 것만 알면 되는 곳에서는, 비확인 응답 모드가 그 애플리케이션에 불필요한 정보를 지닌 메시지를 피할 수 있습니다.

따라서 이 설계는 프로토콜 오버헤드와 인식적 강도를 연동된 선택으로 다룹니다.

1997년 프로토콜을 읽는 이례적으로 유용한 방식은 이것입니다. 패킷 목록이 아니라, 지식의 가격표로 읽는 것입니다.