我有一个生产者向RabbitMQ交换机发送持久消息。如果RabbitMQ内存或磁盘超过水印阈值,RabbitMQ将阻止我的生产者。文档说它停止从套接字读取,并暂停心跳。
我想要的是在生产者代码中知道我被阻止的方法。目前,即使启用了心跳,一切都会永远停顿。我想收到某种异常,以便我知道我已被阻止,我可以警告用户和/或采取其他行动,但我找不到任何方法来做到这一点。我正在使用Java和C#客户端,并且两者都需要此功能。有什么建议?感谢。
答案 0 :(得分:0)
很抱歉告诉你但是使用RabbitMQ(至少2.8.6)这是不可能的: - (
有类似的问题,其中心是在连接被阻止时尝试建立频道。结果与您遇到的结果相同。
我对RabbitMQ C#.Net Library的实际核心进行了一些调查,发现问题的根本原因是它进入无限阻塞状态。
您可以在此处查看有关RabbitMQ邮件列表的更多详细信息:
一个建议(我们没有实现)是在一个线程内部进行工作,并让一些其他组件管理超时并在超出线程时终止线程。我们接受了风险: - (
答案 1 :(得分:0)
Rabbitmq使用阻止rpc调用来无限期地侦听回复。
如果您查看Java客户端API,它的作用是:
AMQChannel.BlockingRpcContinuation k = new AMQChannel.SimpleBlockingRpcContinuation();
k.getReply(-1);
现在-1在参数块中传递,直到收到回复。
好消息是你可以传递你的超时以使其返回。 不好的是你必须更新客户端罐子。
如果您可以这样做,则可以在上述阻塞调用的任何地方传递超时。 代码看起来像:
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
仅供参考:我试过这个并且有效。