要約
リモートコンピュータ上で処理を実行させて、その結果を受け取りたい場合にRPC(リモートプロシージャコール)を使用できる。
ただし、不用意にRPCを使用すると処理が複雑になる、コンポーネント間の結合が強くなるなど、あまりいいことないので、以下を参考に本当に使用すべきかを要検討する。
- どの処理がローカルで、どの処理がリモートなのかを関係を明確にする。
- コンポーネント間の依存関係を明確にする。
- リモート側が長時間停止していた場合にどうなるのか?エラーケースを整理して処理できるようにする。
コールバックキュー
RabbitMQを介したRPCシステムを構築する場合は、リクエスト時にレスポンスを受け取る用のキュー(コールバックキュー)もreply_to
として送信する。
queue = channel.queue('', exclusive: true)
exchange = channel.default_exchange
exchange.publish(message, routing_key: 'rpc_queue', reply_to: queue.name)
# ... then code to read a response message from the callback_queue ...
メッセージのプロパティ
persistent
・・・ メッセージを永続的または一時的かを選択する。
content_type
・・・ encordingの設定。JSONでやり取りする場合は、application / json
に設定する。
reply_to
・・・ コールバックキューを指定する(レスポンスを受け取るキューを指定する。)
correlation_id
・・・ RPCリクエストとレスポンスを確認するためのID
Correlation id
このIDを付与してPublishし、Subscribe側はコールバックキューにこのIDを付与してメッセージ返す。
Publish側はこのID比較することでリクエストに対するレスポンスなのかを判断することができる。
サンプル
Serverの動作
- コネクション確立してキュー(rpc_queue)に接続してメッセージを待ち受ける。
- メッセージをうけたら
fibonacci
メソッドを実行する。 fibonacci
メソッドの結果をrouting_key
にreply_to
を指定、correlation_id
を指定してPublishする。
Clientの動作
- コネクション確立してコールバックキュー(amq.gen-xxx)に接続してメッセージ待ち受ける
- キュー(rpc_queue)に
correlation_id
とreply_to
にコールバックキューを指定してメッセージをPublishする。 - Serverからのメッセージをコールバックキューで受け取る。
- Publishした時の
correlation_id
とコールバックキューに返ってきたcorrelation_id
が一致したらresponseを返す。