我正在使用streadway的amqp库来连接rabbitmq服务器.该库提供了一个channel.Consume()函数,它返回一个" < - chan Delivery ".它还提供了一个channel.Get()函数,它返回一个" Delivery "等.
我要实现pop()功能,我正在使用channel.Get().但是,文档说:
"In almost all cases, using Channel.Consume will be preferred."
Run Code Online (Sandbox Code Playgroud)
这里的首选是否意味着推荐?使用channel.Get()而不是channel.Consume()有什么缺点吗?如果是,我如何使用channel.Consume()来实现Pop()函数?
据我所知,是的,"首选"的意思是"推荐".
看来,channel.Get()
不提供的许多功能channel.Consume()
,以及作为并发代码更易于使用,由于它的返回chan
的Delivery
,而不是每个单独Delivery
分开.
提到的多余功能exclusive
,noLocal
并且noWait
,还有一个可选的Table
参数的个数"有队列或服务器特定的语义."
要实现Pop()
使用功能,channel.Consume()
你可以,链接到从一些代码片段AMQP例如消费,创建一个使用信道Consume()
功能,创建一个函数来处理chan
的Delivery
这实际上将实现你Pop()
的功能,然后关火handle()
FUNC中goroutine
.
关键是,如果没有任何接收,通道(在链接示例中)将阻止发送.在该示例中,handle()
func用于range
处理整个通道,直到它为空.Pop()
一个函数可以更好地服务于您的功能,该函数只接收最后一个值chan
并返回它.每次运行它都会返回最新的Delivery
.
编辑:示例函数从通道接收最新值并用它做事(这可能不适用于您的用例,如果函数将Delivery
另一个函数发送chan
到另一个函数进行处理可能会更有用.此外,我还没有没有测试下面的代码,它可能充满了错误)
func handle(deliveries <-chan amqp.Delivery, done chan error) {
select {
case d = <-deliveries:
// Do stuff with the delivery
// Send any errors down the done chan. for example:
// done <- err
default:
done <- nil
}
}
Run Code Online (Sandbox Code Playgroud)
这实际上取决于您要做什么。如果您只想从队列中获取一条消息(第一条消息)basic.get
,则可能应该使用,如果您打算处理队列中的所有传入消息,basic.consume
这就是您想要的。
可能不是平台或库特定的问题,而是协议理解的问题。
UPD
我不太熟悉语言,因此,我将尝试向您简要介绍AMQP细节并描述用例。
您可能会遇到麻烦,basic.consume
有时会产生开销:
有了basic.consume
这样的工作流程:
basic.consume
方法通知代理您要接收消息
basic.consume-ok
来自代理的消息basic.deliver
来自服务器的消息
有了basic.get
这样的工作流程:
basic.get
给经纪人
basic.get-ok
消息或basic.empty
方法的方法,这表示情况服务器上没有可用消息关于同步和异步方法的注意事项:同步是否会有响应,无论异步是否不响应
关于basic.qos
方法prefetch-count
属性的注意事项:当将no-ack
属性设置为basic.consume
或时,它将被忽略basic.get
。
规范中有一条注释basic.get
:“此方法使用同步对话框直接访问队列中的消息,该对话框是为特定类型的应用设计的,其中同步功能比性能更重要”,适用于连续消息消耗。
我的个人测试显示,在RabbitMQ 3.0.1(Erlang R14B04)上以basic.get
(0.38659715652466)排入1000条消息的速度比在basic.consume
(0.17398710250854)上逐一获得1000条消息的速度要快得多,平均超过15%。
如果在主线程中仅消耗一条消息是您的情况-可能必须使用basic.get
。
您仍然只能异步使用一条消息,例如在单独的线程中或使用某种事件机制。有时候,这对于您的机器资源而言将是更好的解决方案,但是您必须注意队列中没有可用消息的情况。
basic.consume
我认为,如果必须一一处理消息,显然应该使用
归档时间: |
|
查看次数: |
3303 次 |
最近记录: |