调用messageProducer.send(message)时如何识别已暂停的queue或broker
解决方案
针对OpenMQ(即原Sun Java Message Queue)的这一特性,有以下几种可落地的方式实现发送时直接抛出异常、避免无限阻塞:
- 调整生产者发送超时配置
OpenMQ客户端默认的生产者发送超时时间为0,代表无限等待,你可以修改连接工厂的imq.jms.producer.sendTimeout属性,设置为合理的毫秒值(比如3000代表3秒超时),当向暂停的队列/不可用的Broker发送消息超过该时间时,客户端会主动抛出JMSException,不会一直阻塞。
如果你是在代码中自定义连接工厂,可以直接配置属性:
如果是由GlassFish等EE容器管理连接工厂,直接在控制台的连接工厂配置项中添加该属性即可。ConnectionFactory cf = new com.sun.messaging.ConnectionFactory(); cf.setProperty("imq.jms.producer.sendTimeout", "3000"); - 前置校验目的地状态
如果你需要在发送前就感知队列暂停状态、避免走到发送逻辑才报错,可以调用OpenMQ暴露的JMX管理接口,通过DestinationMonitorMBean的isPaused()方法主动查询目标队列的运行状态,若查询到队列已暂停,可直接抛出自定义异常或走降级逻辑。 - 使用异步发送API
改用JMS 2.0的异步发送方法messageProducer.send(message, new CompletionListener() {}),该方法不会阻塞当前业务线程,无论队列暂停还是Broker不可用,异常都会通过回调的onException方法返回,你可以在回调中统一处理失败逻辑。 - 调整Broker感知超时(针对Broker暂停场景)
如果你需要更快感知Broker不可用的状态,可以调整两个客户端参数:imq.ping.interval(客户端向Broker发送心跳的间隔,默认30秒)、imq.ack.timeout(客户端等待Broker响应的超时时间),调低这两个值可以让客户端更快识别Broker异常,输出警告或抛出异常。
内容的提问来源于stack exchange,提问作者tagorsim
相关产品推荐
相关产品推荐

