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

长时间无活动后JMS Appender会话报错问题咨询

解决Log4j2 JMS Appender长时间闲置后Session Closed异常

遇到这种长时间无日志活动后抛出Session is closed的问题,其实是很常见的JMS客户端-服务端超时不匹配导致的,结合你的配置和JBoss EAP7的特性,咱们一步步来分析解决:

问题根源

虽然你配置了reconnectIntervalMill="60000",但JBoss EAP7的ActiveMQ Artemis默认会对闲置的会话设置超时回收(默认一般是30分钟)。当你的应用长时间没产生日志,服务端会主动关闭这个闲置会话,而Log4j2的默认JMS Appender可能没有及时检测到会话已失效,当再次发送日志时就会抛出这个异常。

具体解决方案

1. 检查并调整JBoss服务端的会话超时配置

首先登录JBoss服务器,打开standalone.xml(或domain.xml),找到消息子系统的配置段:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:11.0">
    <server name="default">
        <!-- 找到session配置 -->
        <session session-timeout="1800"/> <!-- 默认是1800秒,即30分钟 -->
        ...
    </server>
</subsystem>

如果你的应用可能会有更长时间的日志闲置,可以调大这个session-timeout值,比如设为3600(1小时)或者更大。注意修改后需要重启JBoss生效。

2. 优化Log4j2 JMS Appender的配置

你的现有配置已经开启了immediateFail="false",这是正确的,但可以补充几个参数增强重连能力:

<JMS name="HIFAuditAppender" 
     destinationBindingName="jms/queue/HIFAuditQueue" 
     factoryBindingName="jms/RemoteConnectionFactory" 
     providerURL="http-remoting://hsnban-bil01.bannerlab.int:8080" 
     username="hcmuser" 
     password="gators123=" 
     immediateFail="false" 
     reconnectIntervalMill="60000" 
     reconnectAttempts="10" <!-- 添加最大重连次数 -->
     lookupOnStartup="false" <!-- 每次发送前重新查找JMS资源,避免引用失效 -->
     factoryName="org.jboss.naming.remote.client.InitialContextFactory" />
  • reconnectAttempts:设置最大重连尝试次数,避免无限重连消耗资源
  • lookupOnStartup="false":让Appender在每次发送日志前重新查找连接工厂和队列,避免长时间闲置后资源引用失效

3. 自定义JMS Appender实现主动重连

如果默认的重连逻辑还是无法覆盖场景,可以扩展Log4j2的JmsAppender,在捕获到Session is closed异常时主动重新初始化连接和会话:

import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.appender.jms.JmsAppender;
import org.apache.logging.log4j.core.LogEvent;

public class ReconnectableJmsAppender extends JmsAppender {

    @Override
    protected void send(final LogEvent event) {
        try {
            super.send(event);
        } catch (AppenderLoggingException e) {
            // 检查是否是Session closed异常
            if (e.getCause() instanceof IllegalStateException 
                && "Session is closed".equals(e.getCause().getMessage())) {
                // 停止并重新启动Appender,重建连接和会话
                try {
                    this.stop();
                    this.start();
                    // 重新发送日志事件
                    super.send(event);
                } catch (Exception reinitException) {
                    throw new AppenderLoggingException("Failed to reinitialize JMS connection", reinitException);
                }
            } else {
                // 其他异常直接抛出
                throw e;
            }
        }
    }
}

然后在log4j2配置文件里使用这个自定义Appender(注意配置正确的类全路径):

<ReconnectableJms name="HIFAuditAppender" 
                  destinationBindingName="jms/queue/HIFAuditQueue" 
                  factoryBindingName="jms/RemoteConnectionFactory" 
                  providerURL="http-remoting://hsnban-bil01.bannerlab.int:8080" 
                  username="hcmuser" 
                  password="gators123=" 
                  immediateFail="false" 
                  reconnectIntervalMill="60000" 
                  factoryName="org.jboss.naming.remote.client.InitialContextFactory" />

4. 开启调试日志排查重连细节

如果还是不确定问题出在哪,可以开启Log4j2对JMS Appender的调试日志,查看重连过程:

<Logger name="org.apache.logging.log4j.core.appender.jms" level="DEBUG" additivity="false">
    <AppenderRef ref="你的控制台或文件Appender"/>
</Logger>

这样就能看到Appender在异常发生后是否触发了重连,以及重连过程中有没有其他错误,方便定位问题。

总结

核心思路是让客户端的重连机制和服务端的会话超时策略匹配,要么调大服务端的会话超时时间,要么增强客户端的重连逻辑,必要时通过自定义Appender主动处理会话失效的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:58:50