You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

连接中断时调用JMSContext.close()阻塞问题求助

ActiveMQ Artemis客户端重连时close()阻塞问题的解决方法

问题描述

我有一个基于Java SE的ActiveMQ Artemis客户端应用,已在ActiveMQInitialContextFactory配置中设置reconnectAttempts=-1实现连接断开后自动重连,重连功能正常。但当连接处于断开重连状态时,调用JMSContext::stop()或JMSContext::close()会一直阻塞直到重连成功。若不调用这些方法直接停止应用,虽能正常退出(因使用守护线程),但该服务用于对话框场景,必须在关闭时释放占用的资源。

相关配置

java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.ConnectionFactory=tcp://192.168.0.1:1883?retryInterval=200&reconnectAttempts=-1

核心代码

ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");

JMSContext jmsContext = cf.createContext();
jmsContext.setExceptionListener(this::handleJMSException);

Topic topic = jmsContext.createTopic("topicName");
jmsContext.createConsumer(topic).setMessageListener(this::onMessage);

// 对话框关闭逻辑
setOnCloseRequest(dialogEvent -> {
    if(jmsContext != null) {
        jmsContext.close();
    }
});

解决方案

1. 主动终止重连尝试后关闭

直接操作底层ActiveMQ连接,先停止重连机制,再关闭JMSContext,避免阻塞:

setOnCloseRequest(dialogEvent -> {
    if(jmsContext != null) {
        try {
            // 转换为ActiveMQ专属JMSContext并获取底层连接
            ActiveMQConnection connection = (ActiveMQConnection) ((ActiveMQJMSContext) jmsContext).getConnection();
            // 停止重连尝试
            connection.stop();
            // 此时close()不会再阻塞
            jmsContext.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
});

2. 修改连接配置取消阻塞

在连接URL中添加blockOnDurableSend=false参数,禁用持久化消息发送时的阻塞逻辑,从根源减少阻塞场景:

connectionFactory.ConnectionFactory=tcp://192.168.0.1:1883?retryInterval=200&reconnectAttempts=-1&blockOnDurableSend=false

3. 带超时的关闭线程

将close()操作放在单独线程中,设置超时时间,超时后强制中断线程,避免界面卡死:

setOnCloseRequest(dialogEvent -> {
    if(jmsContext != null) {
        Thread closeThread = new Thread(() -> {
            try {
                jmsContext.close();
            } catch (Exception e) {
                Thread.currentThread().interrupt();
            }
        });
        closeThread.start();
        // 设置3秒超时,可根据需求调整
        try {
            closeThread.join(3000);
            if(closeThread.isAlive()) {
                closeThread.interrupt();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
});

4. 监听连接状态优化关闭逻辑

通过异常监听器标记连接断开状态,关闭时针对性处理:

private boolean isConnectionLost = false;

// 初始化时设置异常监听器
jmsContext.setExceptionListener(exception -> {
    handleJMSException(exception);
    isConnectionLost = true;
});

// 对话框关闭逻辑
setOnCloseRequest(dialogEvent -> {
    if(jmsContext != null) {
        if(isConnectionLost) {
            try {
                ActiveMQConnection connection = (ActiveMQConnection) ((ActiveMQJMSContext) jmsContext).getConnection();
                connection.stop();
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
        jmsContext.close();
    }
});

内容的提问来源于stack exchange,提问作者mr mcwolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:17:20