`
guibin
  • 浏览: 363832 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于AMQP实现RPC(Remote Procedure Call)的设计

    博客分类:
  • AMQP
阅读更多
基于AMQP实现RPC(Remote Procedure Call)的设计
guibin.beigjing@gmail.com

首先回忆一下RPC的过程。客户端将请求发送给服务器端,服务器端处理完毕之后将结果返回给客户端。那么在AMQP之上,如何实现RPC呢?客户端应当将请求publish给服务器端,服务器处理完毕之后,再将结果publish回给客户端。在这过程中有两次publish,显然应该是不同的publish。服务器端publish的消息,客户端不应该收到更不应该消费;给客户端publish的结果消息,应该只有客户端能收到;并且对于每次请求和相应,都应该有一组唯一的标识,标识并匹配相应的一对请求和响应,防止由于多次请求而收到多次响应,混淆了请求和响应之间的对应关系。

基于AMQP实现RPC的逻辑如下图所示:


  • 服务器S提前建好一个专门接受来自客户端RPC请求的队列rpc_queue,并且客户端知道如何向此队列publish消息的rountingKey。通常情况下会建立一个和该接受请求的队列同名的rountingKey,并和该rpc_queue绑定。这样客户端向rountingKey发送请求后,服务器端就能收到请求了。
  • 当客户端C启动的时候,生成一个匿名的、排他的、自动删除的回调队列(an anonymous, exclusive and auto delete callback queue),用来接受来自服务器端的响应。
  • 对于一个PRC请求而言,客户端发送的消息必须包含两个属性“ reply_to”和“ correlation_id”。“reply_to”用来告诉服务器端计算后的结果发送到哪个rountingKey,“correlation_id”用做每个请求的唯一标识,以区分不同请求和不同响应。
  • 客户端C将请求publish到rpc_queue,图中上面从左向右的过程。
  • 服务器端S在监听队列rpc_queue,收到了来自客户端的请求之后,处理并得到结果,将结果包装成响应消息,publish给“reply_to”。
  • 客户端C一直在监听“reply_to”队列,收到了结果消息后,取到消息中的属性“correlation_id”值,如果这个“correlation_id”和之前记录的请求的“correlation_id”相匹配,则确认这个响应是有效的,并将结果返回给调用者。

基于此设计,用Scala+RabbitMQ的实现源代码,请参考AIOTrade中的lib.amqp包下的RpcClient.scalaRpcServer.scala

参考文献:
http://www.rabbitmq.com/tutorial-six-python.html
http://www.infoq.com/articles/AMQP-RabbitMQ

Guibin
2011-02-20
  • 大小: 14.4 KB
1
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics