rabbitmq消费者获取消息慢_停止RabbitMQ消费者当前消息(Stop RabbitMQ consumer process current message)...

停止RabbitMQ消费者当前消息(Stop RabbitMQ consumer process current message)

我正在编写一个处理CPU绑定任务的NodeJS服务。 主要想法很简单:

客户端 (浏览器)发送请求

Webserver (NodeJS + ExpressJS)处理请求:生成ID,使用该ID向RabbitMQ添加任务并使用该ID回复客户端。

此外, Web服务器将任务添加到ID为Key的Redis服务器,并将{status: active}作为值

消费者在一分钟内处理一项任务 , 并使用派生结果更新redis条目。

客户端使用此ID来检查相应任务的状态。

问题 :如果客户端停止询问服务器任务是否仍在运行,我希望消费者在步骤4中停止处理任务。 我如何用RabbitMQ做到这一点?

PS:我试图清除队列,但遇到了一些问题:如果消息未被消费者确认,队列不会被清除。 这很可悲,只有在我的CPU绑定任务完成后才会发生。

I'm writing a service on NodeJS that processes CPU-bound tasks. The main idea is pretty simple:

Client (browser) sends request

Webserver (NodeJS + ExpressJS) handles request: generates ID, adds a task to RabbitMQ with that ID and replies to client with that ID.

Also webserver adds the task to Redis server with ID as a key and {status: active} as a value

Consumer processes a task in about a minute and updates redis entry with the derived result.

Client uses this ID to check the status of the corresponding task.

The question: I wish consumer to stop processing the task in the step 4 if client has stopped asking server that the task is still running. How can I do that with RabbitMQ?

P.S.: I've tried to purge the queue but faced with some problems: the queue is not purged if the message was not acknowledged by consumer. As sad here, this will happen only after my CPU-bound task is finished.

原文:https://stackoverflow.com/questions/42715466

更新时间:2020-01-08 04:44

最满意答案

我已经找到了清除消费者的问题,但没有使用RabbitMQ,因为没有找到任何API。

正如在SO上的这个答案中提到的那样,如果消费者应该继续进行操作,我可以检查另一个DB。 所以我决定使用redis来实现这个目的:在工作线程内部,如果密钥尚未过期,我会检查redis中的相关条目。

希望这会对其他人有所帮助。

I've figured out my problem of purging consumer, but without using RabbitMQ, because didn't found any API for that.

As mentioned in this answer on SO, I can check in another DB if the consumer should proceed or not. So I've decided to use redis also for this purpose: inside working thread I check an according entry in redis if the key has not expired yet.

Hope this would be helpful for somebody else.

2017-05-23

相关问答

是的,您的消费者“C”可以捕获与连接相关的故障 。 然后,您可以配置“C”以尝试在捕获此类事件后每隔X秒定期重新连接。 重新连接后,“C”将恢复消耗“Q”消息。 Yes, your consumer, "C" can catch connection-related failures. You can then configure "C" to attempt to reconnect at regular intervals, every X seconds after such an even

...

好像你在这里缺少一些基础知识。 取自这里和我的一些代码。 在消费者线程之外设置连接: //executed once

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("someHost");

factory.setUsername("user");

factory.setPassword("pass");

Connection connection = factory.newConnection();

...

我期望实施 其中三人得到两个消息。 那么简单地使用主题交换并让每个消费者用适当的路由密钥声明它自己的队列。 当你发布的时候,你正在发布一个话题交换(我们称之为E1),例如'request.user.add'和所有绑定到E1的队列都使用匹配的路由密钥(因为我们在这里讨论话题)会得到消息。 或者可以这样说:一条消息从一个队列中消耗一次,并且从一次交换中消耗多少次与队列绑定的消息(使用适当的路由密钥)。 @hirikarate后编辑添加解决方案的问题 那么,我不使用JavaScript,但我会尽力帮助:

...

我只需移动basic_qos调用就可以解决它,将预取计数设置为1 on_channel_create回调方法。 出于某种原因,在basic_consume不够好之前将预取值设置为1。 必须与pika的io循环有关。 I was able to fix it by just moving the basic_qos call to set the prefetch count to 1 on_channel_create call back method. for some reason setti

...

我已经找到了清除消费者的问题,但没有使用RabbitMQ,因为没有找到任何API。 正如在SO上的这个答案中提到的那样,如果消费者应该继续进行操作,我可以检查另一个DB。 所以我决定使用redis来实现这个目的:在工作线程内部,如果密钥尚未过期,我会检查redis中的相关条目。 希望这会对其他人有所帮助。 I've figured out my problem of purging consumer, but without using RabbitMQ, because didn't found

...

事实证明,stop_consuming函数以异步的方式调用了basic_cancel,并在channel.close()函数上进行回调,导致我的应用程序停止其RabbitMQ交互,并且RabbitMQ重新处理unackesdmessages。 实际上已经意识到,随着线程试图稍后确认剩余的任务出现错误,因为通道现在设置为无,因此不再有ack方法。 希望它能帮助别人! turns out the stop_consuming function was calling basic_cancel in a

...

为什么是这样 如Yazan所述,消息是以循环方式从单个队列中消耗的。 您所看到的行为是按设计进行的,因此可以轻松扩展给定队列的使用者数量。 如何更改将每条消息发送给每个消费者的行为? 要让每个使用者收到相同的消息,您需要为每个使用者创建一个队列,并将相同的消息传递给每个队列。 最简单的方法是使用fanout交换。 这会将每条消息发送到绑定到交换机的每个队列,完全忽略路由密钥。 如果需要更多控制路由,可以使用topic或direct交换并管理路由密钥。 但是,无论您选择何种类型的交换,您都需要为每个

...

不,你做不到。 这些都是消费政策。 也许你可以停止发布。 另请阅读以下主题: https : //groups.google.com/forum/#!topic /rabbitmq-users / 68-DPZN4b_Q No you can't do it. These are consuming policies. Maybe you can stop the publish. Read also thread about: https://groups.google.com/forum/#!

...

正如这个答案所指出的那样,RabbitMQ不允许您在发布消息后更改消息。 当您返回false时,RabbitMQ只是将原始消息放回队列中进行处理。 通过使用所需的更改重新发布消息可以获得相同的效果,然后通过返回true来消耗原始消息。 您可能希望使用默认(无名称)交换重新发布消息,以便您可以将其直接发送到您从中获取原始消息的队列。 As this answer points out, RabbitMQ doesn't let you change messages after publishing

...

您可以使用synchronous basic.get方法。 将其包裹在for loop或添加一些计数器。 一旦达到所需数量,就可以使用相应的应用 此方法使用同步对话提供对队列中消息的直接访问,该对话是为特定类型的应用程序设计的,其中同步功能比性能更重要。 You can use synchronous basic.get method. Wrap it in a for loop or add sort of a counter. And quite the app once you reach

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值