要約
リモートコンピュータ上で処理を実行させて、その結果を受け取りたい場合に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を返す。