私の後に繰り返して:
RESTおよび非同期イベントは代替ではありません。それらは完全に直交しています。
どちらか一方、または両方を持つか、どちらも持たないことができます。これらは、まったく異なる問題領域に対応するまったく異なるツールです。実際、汎用の要求/応答通信は、非同期でイベント駆動型であり、フォールトトレラントであることが絶対に可能です。
些細な例として、AMQPプロトコルはTCP接続を介してメッセージを送信します。TCPでは、すべてのパケットは受信者によって確認される必要があります。パケットの送信者がそのパケットのACKを受信しない場合、ACKされるまで、またはアプリケーション層が「あきらめて」接続を放棄するまで、そのパケットを再送信し続けます。すべての「パケット送信要求」には付随する「パケット確認応答」が必要であり、応答に失敗すると接続全体が失敗するため、これは明らかに非フォールトトレラントな要求応答モデルです。非同期フォールトトレラントメッセージング用に標準化され広く採用されているプロトコルであるAMQPは、TCPを介して通信されます!何が得られますか?
ここで重要な概念は、スケーラブルで疎結合のフォールトトレラントメッセージングが、送信方法ではなく、送信するメッセージによって定義されるということです。言い換えると、疎結合はアプリケーション層で定義されます。
RESTful HTTPと直接通信するか、AMQPメッセージブローカーと間接的に通信する2つのパーティを見てみましょう。パーティーAがパーティーBにJPEGイメージをアップロードし、パーティーBがイメージをシャープ、圧縮、またはその他の方法で強化したいとします。パーティAは処理された画像をすぐに必要としませんが、将来の使用と検索のためにそれへの参照を必要とします。RESTで使用できる方法の1つを次に示します。
- パーティAは、HTTP
POST
要求メッセージをパーティBに送信します。Content-Type: image/jpeg
- パーティBは、パーティAが待機している間にイメージを処理します(大きい場合は長時間)。
- パーティ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にルーティングする指示を含むメッセージをメッセンジャーに送信します
- メッセンジャーはパーティAに、処理された画像アドレスを含むパーティBからのメッセージを送信します
- パーティAは、処理された画像への参照を持っているため、作業が完了したと見なします。
- 将来、パーティAが画像を必要とするとき、アドレスを使用して画像を取得します(他のパーティにメッセージを送信することにより)
ここに問題がありますか?どちらの場合も、当事者Aはまで画像アドレスを取得することはできませんした後、乙は、画像を処理します。しかし、パーティAはすぐに画像を必要とせず、すべての権利により、処理がまだ完了していてもそれほど気にすることはできません!
私たちは、Bがその当事者BがAに伝えることによって、かなり簡単にAMQPのケースでこの問題を解決することができ受け入れ Aに画像がどこのアドレスを与える、処理のために画像をなります完了を処理した後に。その後、パーティBは、画像処理が終了したことを示すメッセージを将来Aに送信できます。AMQPメッセージングによる救助!
推測を除いて:RESTで同じことを達成できます。AMQPの例では、「here is the processing image」メッセージを「イメージは処理中です。後で取得できます」というメッセージに変更しました。RESTful HTTPでこれを行うには、202 Accepted
コードをContent-Location
もう一度使用します。
- パーティAはHTTP
POST
メッセージをパーティBに送信しますContent-Type: image/jpeg
- パーティB
202 Accepted
は、処理が終了したかどうか、および処理が完了したときに画像が利用できる場所を説明する何らかの「非同期操作」コンテンツを含む応答を直ちに送り返します。またContent-Location: <link>
、202 Accepted
応答には、応答本文が何であれ、リソースへのリンクであるヘッダーが含まれます。この場合、それは非同期操作へのリンクであることを意味します!
- パーティAは、処理された画像への参照を持っているため、作業が完了したと見なします。
- 将来、パーティーAが処理済みのイメージを必要とするとき、ヘッダーでリンクされている非同期操作リソースを最初にGETして、
Content-Location
処理が終了したかどうかを判断します。その場合、パーティAは非同期操作自体のリンクを使用して、処理されたイメージを取得します。
ここでの唯一の違いは、AMQPモデルで、パーティBがパーティAに画像処理の完了を通知することです。しかし、RESTモデルでは、パーティAは、実際に画像が必要になる直前に処理が行われたかどうかをチェックします。これらのアプローチは同等にスケーラブルです。システムが大きくなると、非同期AMQP戦略と非同期REST戦略の両方で送信されるメッセージの数は、同等の漸近的な複雑さで増加します。唯一の違いは、クライアントがサーバーの代わりに追加のメッセージを送信することです。
しかし、RESTアプローチには、動的発見とプロトコルネゴシエーションというもう少しのトリックがあります。同期と非同期の両方のREST対話がどのように開始されたかを検討してください。パーティAはパーティBにまったく同じリクエストを送信しましたが、唯一の違いはパーティBが応答した特定の種類の成功メッセージです。パーティAが画像処理を同期または非同期のどちらにするかを選択した場合はどうなりますか?パーティAが、パーティ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も、2番目のB非同期もありません同期要求と非同期要求の両方を作成する必要がある場合などに必要です。必要なもの、必要に応じて必要なものを簡単に記述し、ステータスコード、応答コンテンツ、リンクに反応します。加えるCache-Control
は、データのローカルコピーをいつ保持するかを明示的に指示ヘッダー、サーバーはクライアントがローカル(またはオフライン)のコピーを保持できるリソースとネゴシエートできるようになりました。これが、RESTで疎結合のフォールトトレラントマイクロサービスを構築する方法です。