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

MQ服务器宕机时Java客户端持续抛异常的配置优化咨询

IBM MQ客户端重复异常抛出的解决方案(限制次数/停止抛出)

一、连接工厂配置调整

你用的ConfigurableMQQueueConnectionFactory基于IBM原生MQ连接工厂扩展,可通过以下原生参数控制重连行为,减少异常输出:

  • 限制最大重连次数:调用setMaxReconnectAttempts(int),比如设为3,超过次数后停止自动重连,避免无限重试抛异常
  • 拉长重连间隔:用setReconnectInterval(long)设置间隔(单位毫秒),比如设为30000(30秒),降低异常日志的生成频率
  • 关闭自动重连:如果业务允许,直接设置setClientReconnectOptions(WMQConstants.WMQ_CLIENT_RECONNECT_DISABLED),彻底停止自动重连尝试,服务器宕机后只抛一次连接失败异常

二、API代码层面手动控制

在连接、会话创建或消息收发逻辑里,自己封装重试逻辑,避免无限制抛出异常:

  • 设定最大重试次数,超过后仅记录一次最终失败日志,不再循环重试
  • 针对JMSWMQ2002、CC=2;RC=2009这类连接异常,捕获后判断重试次数,达到上限后停止尝试

示例代码:

int maxRetry = 3;
int retryCount = 0;
QueueConnection connection = null;
boolean connected = false;

while (!connected && retryCount < maxRetry) {
    try {
        connection = connectionFactory.createQueueConnection();
        connected = true;
    } catch (JMSException e) {
        retryCount++;
        if (retryCount >= maxRetry) {
            // 仅记录一次最终失败日志,不再抛出
            logger.error("MQ连接失败,已达最大重试次数{}", maxRetry, e);
            break;
        }
        // 间隔递增重试,避免频繁打日志
        try {
            Thread.sleep(10000 * retryCount);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
            logger.error("MQ连接重试被中断", ie);
            break;
        }
        logger.warn("MQ连接失败,正在第{}次重试...", retryCount);
    }
}

三、日志框架过滤重复异常

如果暂时无法修改代码或配置,可通过日志框架(Logback/Log4j)过滤重复的异常日志:

  • 针对特定异常类或错误码,设置只输出有限次数或直接过滤
  • Logback示例配置(过滤RC=2009和JMSWMQ2002异常):
<logger name="com.ibm.mq.jmqi" level="ERROR">
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
        <evaluator>
            <expression>message.contains("CC=2;RC=2009") || message.contains("JMSWMQ2002")</expression>
        </evaluator>
        <onMatch>DENY</onMatch>
        <onMismatch>ACCEPT</onMismatch>
    </filter>
</logger>

或者用DuplicateMessageFilter限制相同日志输出次数:

<appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <filter class="ch.qos.logback.classic.filter.DuplicateMessageFilter">
        <maxDuplicateCount>3</maxDuplicateCount>
        <!-- 相同日志超过3次后不再输出 -->
    </filter>
    <file>/path/to/mq.log</file>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

四、扩展自定义连接工厂

基于你现有的ConfigurableMQQueueConnectionFactory扩展,内置重试次数控制逻辑,统一处理连接异常:

  • 重写连接创建方法,加入重试次数限制,超过次数后仅抛出一次最终异常
  • 示例代码:
public class CustomMQQueueConnectionFactory extends ConfigurableMQQueueConnectionFactory {
    private int maxReconnectAttempts = 3;

    @Override
    public QueueConnection createQueueConnection() throws JMSException {
        int retryCount = 0;
        while (retryCount < maxReconnectAttempts) {
            try {
                return super.createQueueConnection();
            } catch (JMSException e) {
                retryCount++;
                if (retryCount >= maxReconnectAttempts) {
                    throw new JMSException("MQ连接失败,已达最大重试次数" + maxReconnectAttempts, e.getErrorCode());
                }
                try {
                    Thread.sleep(5000 * retryCount);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new JMSException("MQ连接重试被中断", ie);
                }
            }
        }
        throw new JMSException("无法建立MQ连接");
    }

    public void setMaxReconnectAttempts(int maxReconnectAttempts) {
        this.maxReconnectAttempts = maxReconnectAttempts;
    }
}

内容的提问来源于stack exchange,提问作者Dev Drill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:02:11