如何检测基于报警的阻塞RabbitMQ生成器?

如何检测基于报警的阻塞RabbitMQ生成器?,rabbitmq,blocking,alarm,producer-consumer,Rabbitmq,Blocking,Alarm,Producer Consumer,我让生产者向RabbitMQ交换发送持久消息。如果RabbitMQ内存或磁盘超过水印阈值,RabbitMQ将阻止我的生产者。文档中说它停止从套接字读取数据,并暂停心跳 我想要的是在我的生产者代码中知道我被阻止了。目前,即使启用了心跳,一切都会永远暂停。我希望收到某种类型的异常,以便我知道我已被阻止,我可以警告用户和/或采取其他一些操作,但我找不到任何方法来执行此操作。我同时使用Java和C客户机,在这两种情况下都需要此功能。有什么建议吗?谢谢。很抱歉告诉您,RabbitMQ至少在2.8.6中是不

我让生产者向RabbitMQ交换发送持久消息。如果RabbitMQ内存或磁盘超过水印阈值,RabbitMQ将阻止我的生产者。文档中说它停止从套接字读取数据,并暂停心跳


我想要的是在我的生产者代码中知道我被阻止了。目前,即使启用了心跳,一切都会永远暂停。我希望收到某种类型的异常,以便我知道我已被阻止,我可以警告用户和/或采取其他一些操作,但我找不到任何方法来执行此操作。我同时使用Java和C客户机,在这两种情况下都需要此功能。有什么建议吗?谢谢。

很抱歉告诉您,RabbitMQ至少在2.8.6中是不可能做到的:-

有一个类似的问题,主要是当连接被阻塞时试图建立一个通道。结果和你所经历的一样

我对RabbitMQ C.Net库的实际核心进行了一些调查,发现问题的根本原因是它进入了无限阻塞状态

您可以在此处查看RabbitMQ邮件列表的更多详细信息:


我们没有实现的一个建议是在线程内部执行工作,并让其他组件管理超时,如果超过超时,则杀死线程。我们刚刚接受了风险:-

Rabbitmq使用阻塞rpc调用无限期地侦听应答

如果您查看Java客户端api,它所做的是:

    AMQChannel.BlockingRpcContinuation k = new AMQChannel.SimpleBlockingRpcContinuation();
    k.getReply(-1);
现在-1传入参数块,直到收到答复

好的是你可以通过超时来让它返回。 糟糕的是,您必须更新客户端JAR

如果您同意这样做,您可以在任何发出上述阻塞调用的地方传递超时。 代码将类似于:

try {
                    return k.getReply(200);
                } catch (TimeoutException e) {
                    throw new MyCustomRuntimeorTimeoutException("RabbitTimeout ex",e);
                }
在您的代码中,您可以处理此异常并在此事件中执行逻辑

可能需要此修复的某些相关类包括:

com.rabbitmq.client.impl.AMQChannel
com.rabbitmq.client.impl.ChannelN
com.rabbitmq.client.impl.AMQConnection

仅供参考:我已经试过了,效果很好。

谢谢。。。是的,我很害怕。我考虑过杀线的路线,但是太痛苦了。我希望在以后的版本中,可以选择获取异常而不是块。同时,我实现了一个轮询线程,它关注内存和磁盘警报以及使用和限制。如果使用情况接近可能很快设置警报的位置,我会采取措施避免被阻止并警告用户。On说RabbitMQ提供了AMQP 0-9-1的扩展,允许在连接被阻止时通知客户端。