RabitMQ----RPC

在这小节,使用RabitMQ构建RPC:一个客户端和一个可扩展的RPC 服务器。

回调队列(callback queue)

通常情况下在RabitMQ上实现RPC是很容易的。客户端发送请求消息,服务器给出响应消息。为了接收响应,需要发送有回调队列地址的请求。

以下demo使用的默认的队列:

q, err := ch.QueueDeclare(
  "",    // name
  false, // durable
  false, // delete when usused
  true,  // exclusive
  false, // noWait
  nil,   // arguments
)

err = ch.Publish(
  "",          // exchange
  "rpc_queue", // routing key
  false,       // mandatory
  false,       // immediate
  amqp.Publishing{
    ContentType:   "text/plain",
    CorrelationId: corrId,
    ReplyTo:       q.Name,
    Body:          []byte(strconv.Itoa(n)),
})

消息属性(message properties)

AMQP  0-9-1 协议为每个消息预定义了14个属性,但是除了以下这几个,其他的几乎没有被使用过。

persistent:标记该消息为持久化的;

content_type:用来描述编码的mime类型,例如经常使用json格式:application/json;

reply_to:通常用来命名一个回调队列;

correlation_id : 有助于将RPC的请求与响应联系起来。

correlation id

在上面呈现的方法中,我们建议为每个RPC请求创建回调队列。这相当低效,但是这里有个更好的办法:为每个客户端创建一个单独的回调队列。

但是这又出现了一个新的问题:在队列里接收到响应消息后,不清楚该响应应该属于哪个请求。

当设置correlation_id属性以后,为每个请求设置唯一的correlation_id,然后当在回调队列里接收到消息后就查看该correlation_id属性,基于此,就能将响应与请求匹配起来。

如果看到未知的correlation_id的值,我们就可以安全的丢弃该消息---不属于我们的请求。

也许你会问:在回调队列里为什么要忽略掉未知的消息,而不是仅仅以error报错。那是由于服务器端可能出现资源竞争。虽然不太可能,但是RPC服务器会在发送响应后并且发送请求的确认消息到达之前会死掉。如果这个发生,那么重启RPC服务器后将再次处理该请求。那就是为什么在客户端必须优雅的处理重复响应而且RPC应该是幂等的。

幂等:RPC 系统通常会提供至少一次或最多一次的语义,或者在两者之间选择。如果需要了解应用程序的性质和远程过程的功能是否安全,可以通过多次调用同一个函数来验证。如果一个函数可以运行任何次数而不影响结果,这是幂等(idempotent)函数的,如每天的时间、数学函数、读取静态数据等。否则,它是一个非幂等(nonidempotent)函数,如添加或修改一个文件)。

rpc工作原理:

1.当客户端启动,会创建一个异步专用的回调队列。对于一个RPC请求, 客户端会发送一个有reply_to属性(设置回调队列)和correlation_id属性(为该请求设置唯一值)的message。

2.该请求会被发送到rpc_queue。

3.服务器等待接收来自rpc_queue的请求。当有请求到达的时候,服务器接收请求并且使用reply_to指定的回调队列响应结果给客户端。

4.客户端等待来自回调队列的数据。当响应消息到达的时候,客户端会校验correlation_id属性,如果correlation_id的值与发送请求时候的值匹配,就会返回对应程序的响应。

通常,通过建立连接、通道和声明队列开始。如果想运行多个服务器端进程,为了实现多个服务器间的负载均衡,需要在通道设置prefetch属性。

使用Channel.Consume得到从队列接收消息的go channel。












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值