使用channel.Get()而不是channel.Consume()有缺点吗?

pym*_*ymd 8 amqp go rabbitmq

我正在使用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()函数?

Int*_*net 6

据我所知,是的,"首选"的意思是"推荐".

看来,channel.Get()不提供的许多功能channel.Consume(),以及作为并发代码更易于使用,由于它的返回chanDelivery,而不是每个单独Delivery分开.

提到的多余功能exclusive,noLocal并且noWait,还有一个可选的Table参数的个数"有队列或服务器特定的语义."

要实现Pop()使用功能,channel.Consume()你可以,链接到从一些代码片段AMQP例如消费,创建一个使用信道Consume()功能,创建一个函数来处理chanDelivery这实际上将实现你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)


pin*_*ain 5

这实际上取决于您要做什么。如果您只想从队列中获取一条消息(第一条消息)basic.get,则可能应该使用,如果您打算处理队列中的所有传入消息,basic.consume这就是您想要的。

可能不是平台或库特定的问题,而是协议理解的问题。

UPD

我不太熟悉语言,因此,我将尝试向您简要介绍AMQP细节并描述用例。

您可能会遇到麻烦,basic.consume有时会产生开销:

有了basic.consume这样的工作流程:

  1. 发送basic.consume方法通知代理您要接收消息
    • 虽然这是一种同步方法,但是请等待basic.consume-ok来自代理的消息
  2. 开始收听basic.deliver来自服务器的消息
    • 这是一种异步方法,在服务器上没有可用消息的情况下,例如,限制阅读时间,您应该自己小心

有了basic.get这样的工作流程:

  1. 发送同步方法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我认为,如果必须一一处理消息,显然应该使用