나를 따라 반복
REST 및 비동기 이벤트는 대안이 아닙니다. 그들은 완전히 직교합니다.
둘 중 하나를 가질 수 있습니다. 그것들은 완전히 다른 문제 영역을위한 완전히 다른 도구입니다. 실제로, 범용 요청-응답 통신은 절대적으로 비동기식, 이벤트 중심 및 내결함성이 있습니다.
간단한 예로, AMQP 프로토콜은 TCP 연결을 통해 메시지를 보냅니다. TCP에서 모든 패킷은 수신자가 확인해야합니다 . 패킷을 보낸 사람이 해당 패킷에 대한 ACK를받지 못하면 해당 패킷이 ACK 될 때까지 또는 응용 프로그램 계층이 "제공"하여 연결을 포기할 때까지 해당 패킷을 다시 보냅니다. 모든 "패킷 전송 요청"때문에 명확하게 비 내결함성 요청 - 응답 모델이다 있어야 실패 전체 연결의 응답 결과에 첨부 된 "패킷 수신 확인 응답", 실패가있다. 그러나 비동기식 내결함성 메시징을 위해 표준화되고 널리 채택 된 프로토콜 인 AMQP는 TCP를 통해 통신됩니다! 무엇을 제공합니까?
여기서 핵심 개념은 확장 가능한 느슨하게 결합 된 내결함성 메시징이 메시지 전송 방식이 아니라 전송하는 메시지에 의해 정의된다는 것 입니다. 다시 말해, 느슨한 결합은 응용 계층에서 정의됩니다 .
RESTful HTTP와 직접 또는 AMQP 메시지 브로커와 간접적으로 통신하는 두 당사자를 살펴 보자. 당사자 A가 이미지를 선명하게하거나 압축하거나 향상시키는 JPEG 이미지를 당사자 B에 업로드한다고 가정합니다. 당사자 A는 처리 된 이미지를 즉시 필요로하지 않지만 나중에 사용하고 검색하기 위해 이미지를 참조해야합니다. REST에 들어갈 수있는 한 가지 방법은 다음과 같습니다.
- 당사자 A는 다음과 같이 HTTP
POST
요청 메시지를 당사자 B 에게 보냅니다.Content-Type: image/jpeg
- 파티 A가 대기하는 동안 파티 B는 이미지를 처리하고 (큰 경우 오랫동안) 다른 작업을 수행 할 수 있습니다.
- 당사자 B는 처리 된 이미지에 링크
201 Created
되는 Content-Location: <url>
헤더 와 함께 HTTP 응답 메시지를 당사자 A 에게 보냅니다.
- 파티 A는 이제 처리 된 이미지에 대한 참조가 있으므로 작업이 완료된 것으로 간주합니다.
- 나중에 당사자 A가 처리 된 이미지를 필요로하는 경우 이전
Content-Location
헤더 의 링크를 사용하여 이미지를 가져옵니다.
201 Created
응답 코드는 자신의 요청이 성공적으로뿐만 아니라 클라이언트를 알려줍니다, 그것은 또한 새로운 자원을 만들었습니다. 201 응답에서 Content-Location
헤더는 작성된 자원에 대한 링크입니다. 이것은 RFC 7231 섹션 6.3.2 및 3.1.4.2에 지정되어 있습니다.
이제이 상호 작용이 AMQP의 가상 RPC 프로토콜을 통해 어떻게 작동하는지 살펴 보겠습니다.
- 당사자 A는 이미지를 포함하는 AMQP 메시지 브로커 (메신저라고 함)를 전송하고 처리를 위해 이미지를 당사자 B로 라우팅하기위한 지시 사항을 보낸 다음 이미지에 대한 일종의 주소로 당사자 A에 응답합니다.
- 파티 A가 기다렸다가 다른 작업을 수행 할 수 있음
- 메신저는 당사자 A의 원본 메시지를 당사자 B에게 보냅니다.
- 당사자 B가 메시지를 처리
- B 당사자는 처리 된 이미지의 주소와 해당 메시지를 A 당사자에게 라우팅하기위한 지시 사항이 포함 된 메시지를 Messenger에 보냅니다.
- 메신저는 처리 된 이미지 주소를 포함하는 당사자 B로부터 메시지를 당사자 A에게 보냅니다.
- 파티 A는 이제 처리 된 이미지에 대한 참조가 있으므로 작업이 완료된 것으로 간주합니다.
- 나중에 A 당사자가 이미지를 필요로하는 경우 주소를 사용하여 이미지를 검색합니다 (아마 다른 상대방에게 메시지를 보내서).
여기서 문제가 보입니까? 두 경우 모두, 갑이 될 때까지 이미지 주소를 얻을 수없는 후 파티 B가 이미지를 처리합니다 . 그러나 파티 A는 이미지를 즉시 필요로하지 않으며, 모든 권리에 의해 처리가 아직 완료되면 더 이상 신경 쓰지 않아도됩니다!
AMQP 사례에서 B가 A에게 B 가 처리를 위해 이미지를 수락 했다고 알리고 A가 처리가 완료된 후 이미지의 위치를 지정하도록함으로써이를 쉽게 해결할 수 있습니다 . 그러면 파티 B는 나중에 이미지 처리가 완료되었음을 알리는 메시지를 A에게 보낼 수 있습니다. 구조에 AMQP 메시지!
추측하지 말고 REST로 동일한 것을 달성 할 수 있습니다 . AMQP 예에서 "처리 된 이미지가 있습니다"메시지를 "이미지가 처리 중입니다. 나중에 가져올 수 있습니다"메시지로 변경했습니다. RESTful HTTP에서이를 수행하기 위해 202 Accepted
코드를 Content-Location
다시 사용 합니다.
- 당사자 A는 다음과 같이 HTTP
POST
메시지를 당사자 B 에게 보냅니다.Content-Type: image/jpeg
- 당사자 B는
202 Accepted
처리가 완료되었는지 여부와 처리가 완료되면 이미지를 사용할 수있는 위치를 설명하는 일종의 "비동기 조작"컨텐츠를 포함 하는 응답을 즉시 보냅니다 . 응답에는 응답 본문이 무엇이든 나타내는 리소스에 대한 링크 인 Content-Location: <link>
헤더 도 포함 202 Accepted
됩니다. 이 경우 이는 비동기 작업에 대한 링크임을 의미합니다!
- 파티 A는 이제 처리 된 이미지에 대한 참조가 있으므로 작업이 완료된 것으로 간주합니다.
- 나중에 당사자 A가 처리 된 이미지를 필요로하는 경우, 먼저 처리가 완료되었는지 판별하기 위해 헤더에 링크 된 비동기 조작 자원 을 가져옵니다
Content-Location
. 그렇다면 파티 A는 비동기 작업 자체의 링크를 사용하여 처리 된 이미지를 가져옵니다.
여기서 유일한 차이점은 AMQP 모델에서 파티 B가 이미지 처리가 완료되면 파티 A에 알린다는 것입니다. 그러나 REST 모델에서 당사자 A는 실제로 이미지가 필요하기 직전에 처리가 수행되는지 확인합니다. 이러한 접근 방식은 동일하게 확장 가능 합니다. 시스템이 커짐에 따라 비동기 AMQP와 비동기 REST 전략 모두에서 전송되는 메시지 수가 동일한 점근 적 복잡성으로 증가합니다. 유일한 차이점은 클라이언트가 서버 대신 추가 메시지를 보내는 것입니다.
그러나 REST 접근 방식에는 동적 검색 및 프로토콜 협상과 같은 몇 가지 트릭이 있습니다. 동기화 및 비동기 REST 상호 작용이 어떻게 시작되었는지 고려하십시오. 당사자 A는 당사자 B가 응답 한 특정 종류의 성공 메시지 만 다른 점을 제외하고는 동일한 요청 을 당사자 B 에게 보냈습니다 . 당사자 A가 이미지 처리가 동기식인지 비동기식인지 선택 하려면 어떻게해야 합니까? 당사자 B가 당사자 B가 비동기 처리를 할 수 있는지 여부를 모르는 경우 어떻게합니까?
글쎄, HTTP에는 실제로 이미 표준화 된 프로토콜이 있습니다! HTTP 기본 설정, 특히 respond-async
RFC 7240 섹션 4.1 의 기본 설정이라고 합니다. 당사자 A가 비동기 응답을 원하는 경우 Prefer: respond-async
초기 POST 요청이 있는 헤더를 포함합니다 . 당사자 B가이 요청을 준수하기로 결정하면이 요청 202 Accepted
을 포함하는 응답을 다시 보냅니다 Preference-Applied: respond-async
. 그렇지 않으면, 파티 B는 단순히 Prefer
헤더 를 무시하고 201 Created
평상시처럼 다시 보냅니다 .
이를 통해 당사자 A 는 서버와 협상 하여 대화중인 이미지 처리 구현에 동적으로 적응할 수 있습니다. 또한, 명시 적 링크를 사용한다는 것은 A 당사자가 B 이외의 다른 당사자에 대해 알 필요가 없음을 의미합니다. AMQP 메시지 브로커 없음, 이미지 주소를 실제로 이미지 데이터로 변환하는 방법을 알고있는 신비한 C 당사자 없음, 두 번째 B- 비동기 없음 동기식 요청과 비동기식 요청을 모두 수행해야하는 경우 등을 말합니다. 필요한 것, 원하는 것을 선택하고 상태 코드, 응답 내용 및 링크에 반응합니다. 추가Cache-Control
헤더는 데이터의 로컬 사본을 보관할시기에 대한 명시적인 지침을 제공하며, 이제 서버는 클라이언트가 로컬 (또는 오프라인) 사본을 유지할 수있는 자원과 클라이언트와 협상 할 수 있습니다. 이것이 REST에서 느슨하게 결합 된 결함 허용 마이크로 서비스를 빌드하는 방법입니다.