一次 Java log4j2 漏洞导致的生产问题( 二 )

socket 进行连接,但是没有设置超时时间,当日志中有多个${导致循环调用多次 。所以上面日志打印会重复2次 jndi 的操作,又因为我们日志打印配置了consolerollingFile 。所以会打印四次日志 。
gateway采用 Netty 作为底层容器,采用了Reactor模式,有一个事件循环组负责监听事件,事件到达后会丢给另一个事件循环组去处理读写,事件循环组内有多个事件循环器,每个事件循环器由一个线程去处理业务读写,因此打印上面日志会阻塞住其中一个处理线程 。从dump 出来的单个文件看是只有一个处理线程被阻塞了 。而当进行心跳健康判断的时候,有一定几率会被分配给阻塞的线程,因此会放到队列中一直等待线程处理,进而超时了 把 gateway网关重启了;
四、问题解决办法

参考文档: https://logging.apache.org/log4j/2.x/security.html
建议解决办法
  1. 升级版本 。
    Apache Log4j 2.x >= 2.3.2 (Java 6)Apache Log4j 2.x >= 2.12.4 (Java 7)Apache Log4j 2.x >= 2.17.1 (Java 8 及更新版)
临时解决版本
  1. 删除 JndiLookup.class
    在 2.16.0 以外的任何版本中,您可以JndiLookup从类路径中删除该类:zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
  2. 配置环境变量 LOG4J_FORMAT_MSG_NO_LOOKUPStrue (处理场景有限)
    java opts 配置为 -Dlog4j2.formatMsgNoLookups=true (处理场景有限)
解决后测试
一次 Java log4j2 漏洞导致的生产问题

文章插图
配置完成之后
一次 Java log4j2 漏洞导致的生产问题

文章插图
前者处理为56秒,后者需要的时间为354ms. 是正常的响应时间 。

经验总结扩展阅读