为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
暮色呼如 2021-06-15 09:16:26
我正在使用streadway 的amqp库来连接rabbitmq 服务器。该库提供了一个 channel.Consume() 函数,它返回一个“ <-chan Delivery ”。它还提供了一个 channel.Get() 函数,该函数除其他外返回“交付”。我必须实现一个pop()功能,我正在使用channel.Get()。但是,文档说:"In almost all cases, using Channel.Consume will be preferred."这里的首选是指推荐吗?使用 channel.Get() 而不是 channel.Consume() 有什么缺点吗?如果是,我如何使用 channel.Consume() 来实现 Pop() 函数?
查看完整描述

2 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

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

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

UPD

我不太熟悉它的 go 语言,所以我会尽量给你一些关于 AMQP 细节的简要介绍并描述用例。

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

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

  1. Sendbasic.consume方法通知broker你想接收消息

    • 虽然这是一个同步方法,但等待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

Spec 有一个注释basic.get:“此方法使用同步对话提供对队列中消息的直接访问,该同步对话是为特定类型的应用程序设计的,其中同步功能比性能更重要”,适用于连续消息消费。

我的个人测试表明,在 RabbitMQ 3.0.1、Erlang R14B04 上,使用basic.get(0.38659715652466) 获取 1000 条消息比逐行获取 1000 条消息 (0.47398710250854) 快basic.consume15% 以上。

如果您只在主线程中使用一条消息 - 可能您必须使用basic.get.

您仍然可以仅异步使用一条消息,例如在单独的线程中或使用某些事件机制。有时这对您的机器资源来说是更好的解决方案,但您必须注意队列中没有可用消息的情况。

如果你必须一一处理消息很明显basic.consume应该使用,我认为


查看完整回答
反对 回复 2021-06-21
  • 2 回答
  • 0 关注
  • 221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信