Logback在springboot应用中的common工程共通配置和日志名变量等问题解决方案

Logback在springboot应用中的common工程共通配置和日志名变量等问题解决方案

Logback是Java项目中最常见的日志框架了,不过随着云技术的相关诞生,很多日志已经不用再手动配置生成了。例如常见的K8S容器中就有日志,或者普通的应用日志利用ELK EFK之类的放到ES里面去,本地几乎不留什么日志,那么我为何要写这篇尴尬的文章呢?

因为在这个过程中,有些有趣的和值得记录的事情发生,所以想记录下来与君共勉。如果有幸读到这篇文章的你,刚好遇到需要自己配置Logback,场景和问题与我一样,那或许能帮你少走些弯路也不错。

场景

需求:通过Web接口来查看和下载应用日志日志。

问题:因为我这个项目结构的关系,想在应用本身中生成一个默认的日志文件,用来通过Web接口下载,所以容器的输出流格式的日志没办法获取历史的,总不能把K8S的接口给出来啊,就只能保留应用日志了。自己做日志持久,还不如就用现成的Logback,于是就想把配置的部分当成默认值,直接放到common工程去,就省得开发人员还要改子工程的代码了…然而理想很丰满,现实很骨感…读到这里的你,是不是也觉得so easy?那就来吧,看看我遇见的坑↓

这两天我遇到的坑

  1. logback的共通配置文件放到resource,却读不到?
  2. 如何把logback生成的日志文件配置成和工程名一致呢?
  3. 配置好了logback启动后,为什么会出现多余的日志文件呢?明明没有只有自己的配置,这个是怎么的多出来的(xxxxxxxxx_IS_UNDEFINED)?
  4. logback的filenamepattern只能写静态的日志名,即便是支持变量,也只有日期,数量之类的,不能动态的读取工程名(我就想把日志名动态设置成和项目名一样,为什么就这么费劲,这个需求难道之前没人做过)?
  5. 本地启动明明没啥问题,部署到k8s上就找不到配置文件,连控制台都打印不出日志,什么情况啊?

小坑还有…但都不重要了,就挑这几个大坑说吧。

logback的共通配置文件放到resource,却读不到?

说实话,这个问题其实是我自己对于logback的配置想当然了,所以范的一个典型不看文档而发生错误的例子。如果能仔细看看文件,也不会发生了。

一上来我就认为,不就是logback嘛,我从别的项目里面copy过来一个logback.xml改改,然后丢到common工程,这样就行了吧~~结果,打脸打的啪啪的。日志是有了,但是多了一堆没用的日志,而且还全是一个名,根本分不清是哪个工程的(因为只是测试看看效果,文件名就起的很随意,结果等到要解决第3个问题时,困扰了好长时间,这个容后文详解)
为了让大家看的不那么蒙圈,我先讲一下我的项目结构:
A框架工程
|---- a-comm 框架工程的common包

B项目工程 pom依赖A框架工程
|---- b-comm 业务工程的common包
|-----b-order 业务工程的order子工程

下面看我最初的logback配置文件,大家一定很熟悉了。
a-comm/src/main/resources/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/base.xml" />

  <!-- 定义日志文件的存储地址 如果变量没定义就是用:后的默认值 只有scope=context的才能在代码中访问到-->
  <property name="LOG_HOME" value="${BOOT_LOGHOME:-logs}" scope="context"/>
  <!-- 日志名称 -->
  <property name="LOG_NAME" value="testlog" scope="context"/>

  <!-- 开发环境 -->
  <springProfile name="dev">
    <!-- 注意这里一定要放到springProfile里, 否则在本机执行的时候还是会去创建相应的文件,但不会输出内容,定义在里面也不会影响ref引用 -->
    <!-- 按照每天生成日志文件 -->
    <appender name="FILE"
      class="ch.qos.logback.core.rolling.RollingFileAppender">
      <rollingPolicy
        class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!--日志文件输出的文件名 -->
        <FileNamePattern>${LOG_HOME}/${LOG_NAME}_%d{yyyy-MM-dd}.%i.log
        </FileNamePattern>
        <!--日志文件保留天数 -->
        <maxHistory>15</maxHistory>
        <!--日志文件最大的大小 -->
        <MaxFileSize>10MB</MaxFileSize>
        <!--日志文件的上限大小,到了阀值就会删除旧的日志 -->
        <totalSizeCap>10GB</totalSizeCap>
      </rollingPolicy>
      <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
      </encoder>
    </appender>

    <!-- 文件输出 -->
    <appender name="asyncFileAppender" class="ch.qos.logback.classic.AsyncAppender">
      <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
      <discardingThreshold>0</discardingThreshold>
      <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
      <queueSize>2048</queueSize>
      <includeCallerData>true</includeCallerData>
      <!-- 添加附加的appender,最多只能添加一个 -->
      <appender-ref ref="FILE" />
    </appender>

    <root level="INFO">
      <appender-ref ref="console" />
      <appender-ref ref="asyncFileAppender" />
    </root>
  </springProfile>
</configuration>

这根本不是我想要的效果,那就继续改吧。那就把logback.xml改成include节点,在项目的common工程中引用,这样总行了吧,logback-comm.xml的配置不影响子工程,虽然子工程多个一个共同的配置文件,但也无伤大雅,而且这样还有利于子工程拓展自己的logback配置,一举两得。于是乎改成了这样:

a-comm/src/main/resources/logback-comm.xml

<?xml version="1.0" encoding="UTF-8"?>
<included>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
  
  <!-- 定义日志文件的存储地址 如果变量没定义就是用:后的默认值 只有scope=context的才能在代码中访问到 -表示当前目录 -->
  <property name="LOG_HOME" value="${BOOT_LOGHOME:-logs}" scope="context" />
   <!-- 日志名称 -->
  <property name="LOG_NAME" value="testlog" scope="context"/>
  
  <!-- 将状态信息监听器设置为无操作监听器 不显示logback本身的这些类似 15:40:01,795 |-INFO in ch.qos.logback.xxxxx的相关日志 -->
<!--   <statusListener class="ch.qos.logback.core.status.NopStatusListener" /> -->
  
  <!-- 按照每天生成日志文件 -->
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!--日志文件输出的文件名 -->
      <FileNamePattern>${LOG_HOME}/${LOG_NAME}_%d{yyyy-MM-dd}.%i.log
      </FileNamePattern>
      <!--日志文件保留天数 -->
      <maxHistory>7</maxHistory>
      <!--日志文件最大的大小 -->
      <MaxFileSize>20MB</MaxFileSize>
      <!--日志文件的上限大小,到了阀值就会删除旧的日志 -->
      <totalSizeCap>1GB</totalSizeCap>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
      <charset>UTF-8</charset>
    </encoder>
  </appender>
  <!-- 注意这里一定要放到springProfile里, 否则在本机执行的时候还是会去创建相应的文件,但不会输出内容,定义在里面也不会影响ref引用 -->
  <root level="INFO">
      <appender-ref ref="CONSOLE" />
      <appender-ref ref="FILE" />
  </root>
</included>

就是这里 我想当然的认为这样写可以,都在资源目录里面,应该能找的到吧?启动,呵呵,打脸…
b-comm/src/main/resources/logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="a/a-comm/logback-comm.xml"/>
</configuration>

然后仔细翻了一下logback的配置文档,解决了,应该写成完整的包名,把xml放到包名所在的目录里面去,所以共通xml的路径应该是这样:
a-comm/src/main/java/com/a/comm/logging/logback-comm.xml
而业务comm工程的引用格式应该=完整包名+文件名
com/a/a-comm/logging/logback-comm.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="com/a/comm/logging/logback-comm.xml"/>
</configuration>

启动~OK!第一个问题就搞定了。

如何把logback生成的日志文件配置成和工程名一致呢?

这个比较容易,logback提供了springProperty节点,可以用来接spring的配置文件中的环境变量值。于是把
<property name="LOG_NAME" value="testlog" scope="context"/>
配置替换成
<springProperty scope="context" name="LOG_NAME" source="spring.application.name" />
就ok啦!所以文件又变成这样
a-comm/src/main/resources/logback-comm.xml

<?xml version="1.0" encoding="UTF-8"?>
<included>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
  <springProperty scope="context" name="LOG_NAME" source="spring.application.name" />
  
  <!-- 定义日志文件的存储地址 如果变量没定义就是用:后的默认值 只有scope=context的才能在代码中访问到 -表示当前目录 -->
  <property name="LOG_HOME" value="${BOOT_LOGHOME:-logs}" scope="context" />
  ....
</included>

b-order/src/main/resources/application.yml

spring:
  application:
    name: b-order

ok,启动看看~结果生成了这么两个日志文件

_IS_UNDEFINED.0.log
b-order.0.log

so,我们要的b-order.0.log日志有了,但是这个_IS_UNDEFINED.0.log是什么鬼????作为一个患有完美强迫症的程序员,绝不允许这种莫名其妙的东西出现!!!

配置好了logback启动后,为什么会出现多余的日志文件呢?明明没有只有自己的配置,这个是怎么的多出来的(_IS_UNDEFINED)?

造成这个问题的原因有几种,首先你要确定是否真的在你的工程中只有你的logback生效了,因为有可能在其他依赖工程的jar中,同样存在着logback的配置。

但我的这个工程我很熟悉,就是这一个生效的配置,为什么会多出了这么一个_IS_UNDEFINED的日志文件呢?看起来好像不是配置的问题了,应该是和logback的默认值有关吧?logback.xml配过无数个了,那为什么以前那么多项目,怎么没出现过这个问题呢,奇怪啊?沿着这个思路Debug跟踪了一下。这个问题最后发现是因为logback在spring启动时配置了2次。划重点!!!
日志文件生成:

一次是Spring Cloud的配置加载的,一次是Spring Boot配置加载的。

这回真相大白了!而这个_IS_UNDEFINED正是由于Spring Cloud的配置读取到了我们的a-comm/src/main/java/com/a/comm/logging/logback-comm.xml配置文件中<springProperty scope="context" name="LOG_NAME" source="spring.application.name" />作为日志名变量,但工程的cloud配置文件bootstrap*.yml中并没有指定对应的名称,因为我们只在springboot的配置文件b-order/src/main/resources/application.yml中声明了spring.application.name,cloud的那个没有获取到,所以就变成_IS_UNDEFINED了!

所以你的工程如果只用了spirngboot,那么不会有这个问题的。可如果你的项目中用了springboot+springcloud,还在common配置了logback的话,就会有这个问题了!

既然找到的问题的原因,那么改正就有思路了,把日志名配置成cloud和boot都能获取到的变量不就行啦??思路是没问题了,但现实就是这么残酷,当初放在comm就是为了减少子工程的配置,如果按上面这个方案,那就只能在各个子工程单独增加logback的配置,那不就偏离了初衷了嘛??挠头…挠头…难道就这么个简单的问题,我就想在comm中配置logback,并指定日志名和工程名一样,难道就不行??我不相信!!!然后不信邪的我就开始各种Google和百度,结果…没有!真没有!或许是我没找到吧?但这么大的世界,就只有我一个有这么奇葩的想法吗?不会吧?反复质疑查询了很多遍,就是没找到相关的东西。放弃!靠人不如靠己,有这搜索的功夫,我自己都写出来了,那就自己写吧!我自己写一个总可以了吧?

logback的filenamepattern只能写静态的日志名,即便是支持变量,也只有日期,数量之类的,不能动态的读取工程名(我就想把日志名动态设置成和项目名一样,为什么就这么费劲,这个需求难道之前没人做过)?

于是就开启了我折腾日志文件名的艰辛历程~
首先需要一个属性定义器~这个东西就是logback实现自定义属性而创造的。于是就有了如下代码

/**
 * 日志名称获取器
 */
public class LoggingPropertyDefinerBase extends PropertyDefinerBase {
    private Logger logger = LoggerFactory.getLogger(LoggingPropertyDefinerBase.class);
    private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    /**
     * 获取默认的日志名称 ${spring.application.name}
     * 
     * @return
     */
    private String getLogName() {
        String logName = "";

        // 因为此处logback初始化的太早了 spring还没有加载 所以没有读取的环境变量 只能自己读取了
        Resource[] resources = null;
        try {
            // 加载当前classpath中所有的application*.yml
            resources = resolver.getResources("classpath:application*.yml");
        } catch (IOException e) {
			logger.error("exception in LoggingPropertyDefinerBase.getLogName.getResources with {}", e)
        }
        if (resources != null && resources.length > 0) {
            for (Resource res : resources) {
                // 把yml读取成map
                Map<String, Object> info = YmlUtil.yml2Map(res);
                // 读取application名
                String appName = ConverterUtil.toString(info.get("spring.application.name"));
                // 如果找到了就直接返回
                if (ConverterUtil.isNotEmpty(appName)) {
                    logName += (appName);
                    break;
                }
            }
        }
        return logName;
    }

    @Override
    public String getPropertyValue() {
        return getLogName();
    }
}

有了这个属性定义器,咱们就可以给logback加自定义的属性啦~~~下面改造一下,加一个默认值
a-comm/src/main/java/com/a/comm/logging/logback-comm.xml

  <define name="defLogName" class="com.a.comm.logging.LoggingPropertyDefinerBase"/>
  <!-- 读取spring.application.name中的属性来生成日志文件名 所以需要要求日志的配置要配置在项目的application.yml中 不要放到bootstrap.yml中 否则会出现两个日志文件 -->
  <springProperty scope="context" name="LOG_NAME" source="spring.application.name"  defaultValue="${defLogName}"/>

ok了,启动试试!如期的,cloud和boot的两次加载都获取到了application.yml中的配置(还是会走两次,但两次文件名一致,所以cloud和boot的日志会写到同一个文件里),这样就只剩一个b-order.0.log啦!好,就这样吧~~









------------------------------------------你以为这样就结束了么?和我一样的天真-------------------------------------

本地启动明明没啥问题,部署到k8s上就找不到配置文件,连控制台都打印不出日志,什么情况啊?

开发环境一点问题没有,一部署到测试环境就凉凉,先是一点日志都不打,容器日志一片空白,以至于K8S认为进程没有启动成功,一个劲的LOOP重启。于是版本回滚,开始查找问题。

为什么会什么日志都没有了呢?肯定是刚刚加的东西导致的,那么什么东西找不到了才会不显示日志呢?连正常的输出流都不打印,更别说文件了。所以,那应该是找不到
a-comm/src/main/java/com/a/comm/logging/logback-comm.xml的问题了,但我本地好使啊?做了这么多年开发,自以为是,想当然的觉得我本地环境和测试一样,应该没啥问题,直接上吧,所以就连试都没试,结果,唉…不说了,就这么个logback,打了我多少回脸了,脸都打肿了,我还是老老实实的查吧。于是,本地dockerfile编译,启动,进入容器,哇塞,好神奇!真的不好使呀~~和测试环境一样呢////////什么情况啊?////////////

于是反着查,先查docker的镜像,是不是缺少了我的a-comm包?答:否
那是不是a-comm包里面没有logback-comm.xml啊?答:是

哎?原来是logback-comm.xml没有打包到jar里面啊?奇怪啊,明明是xml资源文件啊,为什么不打包呢?查了一下maven配置,发现了,原来logback-comm.xml的路径被我从src/main/resources移动到a-comm/src/main/java/com/a/comm/logging/logback-comm.xml去了,所以打包时候被忽略掉了。因为最开始放到resource了,后来改就忘了…maven默认的打包只打包java目录的class文件的,所以缺少了xml的配置,那就加上吧!于是在a-comm/pom.xml中增加了配置

  <build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
    ...
  </build>

好,重新打包,这回试试吧。稳重点这回,先我本地的docker里面试一下~~哈哈,正常启动啦,配置的日志生成啦~啦~~啦~~~啪啪啪啪啪,博主的脸被抽的血痕累累~~
刚刚解决的日志名的问题,咋又回来啦?还记不记得上文我们发现cloud和boot初始化了两次logback的事情?对,它又出现了!就是这个undefined!

_IS_UNDEFINED.0.log
b-order.0.log

我自己写的动态获取springboot的配置文件都不好使的嘛?这么神奇吗?于是,继续查吧~
本来想着LoggingPropertyDefinerBase里面也没几行代码,肯定是cloud加载的时候找不到application.yml了。不过我用的可以spring自己的classloader啊PathMatchingResourcePatternResolver!官方的加载器能加载不出资源文件?不可能吧?打个log试试!
于是代码就改成了这样:

		.......
        if (resources != null && resources.length > 0) {
        	......
        } else {
        	logger.debug("not found resources with resolver.getResources(\"classpath:application*.yml\");")
        }

ok,运行一下试试~唉?不对啊,为什么没显示?我的日志呢?输出流,文件里面都没有。我新加的这条logger.debug的日志哪去了?????这么神奇吗?哦,应该是在logback初始化的阶段,logback还没有初始化完成,我用LoggerFactory.getLogger(LoggingPropertyDefinerBase.class);获取的日志对象还没有创建出来,所以这样写打不出来日志的,要是能打出来日志才奇怪呢!!!在想明白了这点后,那么问题来了,那在logback初始化阶段,logback自己是用什么打印出来的日志呢?于是去logback源码找,终于找到了,logback自己用StatusPrinter或者StatusManager来打印的日志,好吧,把这东西挪到自己的代码里面来,于是类变成了这样:

/**
 * 日志名称获取器
 */
public class LoggingPropertyDefinerBase extends PropertyDefinerBase {
    private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    /**
     * 获取默认的日志名称 ${spring.application.name}
     * 
     * @return
     */
    private String getLogName() {
        String logName = "";

        List<Status> statusList = Lists.newArrayList();

        // 因为此处logback初始化的太早了 spring还没有加载 所以没有读取的环境变量 只能自己读取了
        Resource[] resources = null;
        try {
            // 加载当前classpath中所有的application*.yml
            resources = resolver.getResources("classpath:application*.yml");
        } catch (IOException e) {
            ErrorStatus es = new ErrorStatus("exception in LoggingPropertyDefinerBase.getLogName() PathMatchingResourcePatternResolver.getResources", this, e);
            statusList.add(es);
        }
        if (resources != null && resources.length > 0) {
            for (Resource res : resources) {
                // 把yml读取成map
                Map<String, Object> info = YmlUtil.yml2Map(res);
                // 读取application名
                String appName = ConverterUtil.toString(info.get("spring.application.name"));
                // 如果找到了就直接返回
                if (ConverterUtil.isNotEmpty(appName)) {
                    logName += (appName);
                    break;
                }
            }
        }
        // 打印status日志
        InfoStatus is = new InfoStatus("LoggingPropertyDefinerBase gender default log name = " + logName, this);
        statusList.add(is);
        if (statusList.size() > 0) {
            StatusPrinter.print(statusList);
        }
        return logName;
    }

    @Override
    public String getPropertyValue() {
        return getLogName();
    }
}

运行!于是,终于如愿以偿的看见了日志,的确是没有找到application.yml。那就更奇怪了啊,为什么我本地能找到呢?于是开始打断点一点点调试获取配置文件的过程~~经过几番努力,终于发现了问题。原来spring的classloader的路径,受到了一个系统变量的影响,这个变量的名字叫做loader.path,所有java运行时资源都在这里。而我的docker里面因为做了springboot包的瘦身,lib的内容被分离出去了,所以在jar包用命令运行时,覆盖了loader.path参数
java -jar b-order-lastest.jar -Dloader.path=/env/app-lib
所以导致在docker启动了jar包后,就找不到application.yml配置文件了。因为配置文件抽出后,放在了和jar包同级目录的config目录下
/usr/local/app/config/application.yml
/usr/local/app/b-order.jar
而ClassLoader读取的目录是/env/app-lib,当然就找不到配置文件了~~
好吧,事实往往超出你的想象~你以为神奇的诡异BUG,只是一厢情愿罢了,最终还是会发现原来是自己没有写对代码~现实是残酷的~你懂得的越多,就越会发现自己的无知~

那就分开处理吧,开发环境的走PathMatchingResourcePatternResolver,测试和生产这种用了docker的,就走ResourceUtils,于是就有了如下代码:

package com.wisea.cloud.monitor.logging;
/**
 * 日志名称获取器
 * <p/>
 * 日志中如果发现有初始化2次logback 是因为在bootstrap.yml中配置的关系 如果只在application.yml中配置就会只走一次
 * spring cloud 初始化一次
 * spring boot 初始化一次
 */
public class LoggingPropertyDefinerBase extends PropertyDefinerBase {
    private ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

    /**
     * 获取默认的日志名称 ${spring.application.name}
     * 
     * @return
     */
    private String getLogName() {
        String logName = "";
        List<Status> statusList = Lists.newArrayList();

        // 因为此处logback初始化的太早了 spring还没有加载 所以没有读取的环境变量 只能自己读取了
        List<Resource> resList = Lists.newArrayList();
        try {

            // ResourcePatternResolver读取的是java加载目录 是loader.path
            // 加载当前classpath中所有的application*.yml
            // 一般此处能读到的是开发环境
            Resource[] resArray = resolver.getResources("classpath:application*.yml");
            resList.addAll(Lists.newArrayList(resArray));

            // 如果java加载目录没找到就从运行时目录找
            // 一般此处能读到的 都是jar包和配置分离的测试环境或生产环境
            if (ConverterUtil.isEmpty(resList)) {
                List<File> confList = getDirctoryFiles(ResourceUtils.getFile("/"), ResourceUtils.getFile("config"));
                for (File c : confList) {
                    if (!c.exists()) {
                        continue;
                    }

                    resList.add(new PathResource(c.getAbsolutePath()));
                }
            }
            for (Resource res : resList) {
                // 把yml读取成map
                Map<String, Object> info = YmlUtil.yml2Map(res);
                // 读取application名
                String appName = ConverterUtil.toString(info.get("spring.application.name"));
                // 如果找到了就直接返回
                if (ConverterUtil.isNotEmpty(appName)) {
                    logName += (appName);
                    InfoStatus is = new InfoStatus("find spring.application.name in " + res.getFile().getAbsolutePath(), this);
                    statusList.add(is);
                    break;
                }
            }

        } catch (Exception e) {
            ErrorStatus es = new ErrorStatus("exception in LoggingPropertyDefinerBase.getLogName() PathMatchingResourcePatternResolver.getResources", this, e);
            statusList.add(es);
        }

        // 打印status日志
        InfoStatus is = new InfoStatus("LoggingPropertyDefinerBase gender default log name = " + logName, this);
        statusList.add(is);
        if (statusList.size() > 0) {
            StatusPrinter.print(statusList);
        }
        // 如果没有获取到就用ip地址
        if (ConverterUtil.isEmpty(logName)) {
            List<Inet4Address> localAddresses = Lists.newArrayList();
            try {
                localAddresses = NetworkUtils.getLocalIp4Address();
                if (ConverterUtil.isNotEmpty(localAddresses)) {
                    logName = localAddresses.get(0).getHostAddress();
                }
            } catch (Exception e) {
                ErrorStatus es = new ErrorStatus("exception in LoggingPropertyDefinerBase.getLogName() NetworkUtils.getLocalIp4Address", this, e);
                statusList.add(es);
            }
        }
        return logName;
    }

    /**
     * 查找配置文件
     * 
     * @param filter
     * @param files
     * @return
     */
    private List<File> getDirctoryFiles(File... files) {
        List<File> res = Lists.newArrayList();
        for (File f : files) {
            res.addAll(Lists.newArrayList(f.listFiles((l) -> {
                String n = l.getName();
                return n.startsWith("application") && n.endsWith("yml");
            })));
        }
        return res;
    }

    @Override
    public String getPropertyValue() {
        return getLogName();
    }
}

好了,写到这里就真的结束了。写下这个废话连篇的文章,只是想勉励自己和那些掉到坑里的同志们:

你可以不相信自己,但你要相信机器。在没有绝对的硬件错误情况下,通常出错的都是自己。

程序 [csp] 注册了JDBC驱动程序 [com.alibaba.druid.proxy.DruidDriver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 30-Jun-2025 10:41:03.125 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [csp] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 30-Jun-2025 10:41:03.126 警告 [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[csp]似乎启动了一个为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[ java.lang.Object.wait(Native Method) java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:745)] 30-Jun-2025 10:41:08.216 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/9.0.106 30-Jun-2025 10:41:08.218 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建: Jun 5 2025 19:02:30 UTC 30-Jun-2025 10:41:08.218 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号: 9.0.106.0 30-Jun-2025 10:41:08.218 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统称: Linux 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本: 3.10.0-862.el7.x86_64 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构: amd64 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量: /usr/local/jdk/jre 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本: 1.8.0_44-b02 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商: Oracle Corporation 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /home/csp/apache-tomcat-9.0.106 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /home/csp/apache-tomcat-9.0.106 30-Jun-2025 10:41:08.219 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.config.file=/home/csp/apache-tomcat-9.0.106/conf/logging.properties 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djdk.tls.ephemeralDHKeySize=2048 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dsun.io.useCanonCaches=false 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dignore.endorsed.dirs= 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.base=/home/csp/apache-tomcat-9.0.106 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.home=/home/csp/apache-tomcat-9.0.106 30-Jun-2025 10:41:08.220 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.io.tmpdir=/home/csp/apache-tomcat-9.0.106/temp 30-Jun-2025 10:41:08.221 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 在java.library.path:[/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]上找不到基于APR的Apache Tomcat本机库,该库允许在生产环境中获得最佳性能 30-Jun-2025 10:41:08.401 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"] 30-Jun-2025 10:41:08.419 信息 [main] org.apache.catalina.startup.Catalina.load 服务器在[340]毫秒内初始化 30-Jun-2025 10:41:08.440 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina] 30-Jun-2025 10:41:08.440 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/9.0.106] 30-Jun-2025 10:41:08.453 信息 [main] org.apache.catalina.startup.HostConfig.deployWAR 正在部署web应用程序存档文件[/home/csp/apache-tomcat-9.0.106/webapps/csp.war] 30-Jun-2025 10:41:12.531 信息 [main] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间JSP编译时间。 10:41:12,573 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] 10:41:12,573 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/home/csp/apache-tomcat-9.0.106/webapps/csp/WEB-INF/classes/logback.xml] 10:41:12,574 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath. 10:41:12,574 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [jar:file:/home/csp/apache-tomcat-9.0.106/webapps/csp/WEB-INF/lib/client-collect-api-0.3.28.0.jar!/logback.xml] 10:41:12,574 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/home/csp/apache-tomcat-9.0.106/webapps/csp/WEB-INF/classes/logback.xml] 10:41:12,608 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set 10:41:12,614 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.rolling.RollingFileAppender] 10:41:12,618 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [FILE] 10:41:12,632 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@263577281 - setting totalSizeCap to 200 GB 10:41:12,635 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@263577281 - Archive files will be limited to [100 MB] each. 10:41:12,649 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@263577281 - Will use gz compression 10:41:12,650 |-INFO in c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@263577281 - Will use the pattern ./logs/csp-%d{yyyy-MM-dd}.%i.log.tar for the active file 10:41:12,655 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@3e81a56b - The date pattern is 'yyyy-MM-dd' from file name pattern './logs/csp-%d{yyyy-MM-dd}.%i.log.tar.gz'. 10:41:12,655 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@3e81a56b - Roll-over at midnight. 10:41:12,655 |-INFO in ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP@3e81a56b - Setting initial period to Thu Jun 26 15:58:50 CST 2025 10:41:12,657 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 10:41:12,672 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - Active log file name: ./logs/csp.log 10:41:12,672 |-INFO in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - File property is set to [./logs/csp.log] 10:41:12,673 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 10:41:12,675 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT] 10:41:12,675 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework] to INFO 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [springfox.documentation] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.quartz] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.mybatis] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.pbccrc] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.sine] to DEBUG 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.sine.csp.validate.utils] to DEBUG 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.sine.csp.common.dao] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.sine.csp.serviceresult.dao] to ERROR 10:41:12,677 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO 10:41:12,677 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT] 10:41:12,678 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration. 10:41:12,685 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@4bc614fc - Registering current configuration as safe fallback point . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.7.18) 2025-06-30 10:41:13.285 [background-preinit] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 6.2.5.Final 2025-06-30 10:41:13.307 [main] INFO com.sine.Application - Starting Application v1.0.35-SNAPSHOT using Java 1.8.0_44 on localhost with PID 92930 (/home/csp/apache-tomcat-9.0.106/webapps/csp/WEB-INF/classes started by root in /home/csp/apache-tomcat-9.0.106/bin) 2025-06-30 10:41:13.308 [main] DEBUG com.sine.Application - Running with Spring Boot v2.7.18, Spring v5.3.39 2025-06-30 10:41:13.308 [main] INFO com.sine.Application - The following 1 profile is active: "dev" 2025-06-30 10:41:14.873 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode 2025-06-30 10:41:14.877 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode. 2025-06-30 10:41:14.945 [main] INFO org.springframework.data.repository.config.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 51 ms. Found 0 Redis repository interfaces. 2025-06-30 10:41:15.963 [main] INFO org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 2629 ms 2025-06-30 10:41:16.575 [main] INFO org.springframework.boot.web.servlet.RegistrationBean - Filter xssFilter was not registered (possibly already registered?) 2025-06-30 10:41:17.892 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited 2025-06-30 10:41:20.438 [main] INFO org.springframework.scheduling.quartz.LocalDataSourceJobStore - Using db table-based data access locking (synchronization). 2025-06-30 10:41:20.439 [main] INFO org.springframework.scheduling.quartz.LocalDataSourceJobStore - JobStoreCMT initialized. 2025-06-30 10:41:21.526 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:21.528 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:21.531 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:21.829 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:21.839 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:21.843 [main] INFO org.springframework.aop.framework.CglibAopProxy - Unable to proxy interface-implementing method [public final void org.springframework.scheduling.quartz.QuartzJobBean.execute(org.quartz.JobExecutionContext) throws org.quartz.JobExecutionException] because it is marked as final: Consider using interface-based JDK proxies instead! 2025-06-30 10:41:22.696 [main] WARN org.thymeleaf.templatemode.TemplateMode - [THYMELEAF][main] Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead. 2025-06-30 10:41:23.124 [main] INFO org.springframework.boot.actuate.endpoint.web.EndpointLinksResolver - Exposing 0 endpoint(s) beneath base path '/actuator' 2025-06-30 10:41:23.164 [main] INFO org.springframework.scheduling.quartz.SchedulerFactoryBean - Starting Quartz Scheduler now 2025-06-30 10:41:24.144 [main] INFO com.sine.Application - Started Application in 11.303 seconds (JVM running for 16.22) 2025-06-30 10:41:24.458 [main] INFO org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener - Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2025-06-30 10:41:24.486 [main] ERROR org.springframework.boot.SpringApplication - Application run failed java.lang.IllegalStateException: Failed to execute ApplicationRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:759) at org.springframework.boot.SpringApplication.lambda$callRunners$2(SpringApplication.java:746) at org.springframework.boot.SpringApplication$$Lambda$1079/1133797119.accept(Unknown Source) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:352) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:744) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4491) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:603) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1013) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1861) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:76) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:817) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:468) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1579) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:312) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:776) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:721) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:76) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:211) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:412) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:874) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.startup.Catalina.start(Catalina.java:739) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1383) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1366) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1093) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:421) at org.springframework.data.redis.core.RedisConnectionUtils.fetchConnection(RedisConnectionUtils.java:193) at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:144) at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:105) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) at org.springframework.data.redis.core.RedisTemplate.keys(RedisTemplate.java:896) at com.sine.csp.common.boot.RedisCleanService.run(RedisCleanService.java:27) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:756) ... 56 common frames omitted Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:109) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1595) ... 68 common frames omitted Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:330) at io.lettuce.core.RedisClient.connect(RedisClient.java:216) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider$$Lambda$1084/1822563181.get(Unknown Source) at java.util.Optional.orElseGet(Optional.java:267) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$null$0(LettucePoolingConnectionProvider.java:97) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider$$Lambda$1082/1664936139.get(Unknown Source) at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:211) at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:201) at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:70) at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:571) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:298) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:223) at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:122) at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:117) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:103) ... 69 common frames omitted Caused by: io.lettuce.core.RedisCommandExecutionException: NOAUTH HELLO must be called with the client already authenticated, otherwise the HELLO AUTH <user> <pass> option can be used to authenticate the client and select the RESP protocol version at the same time at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147) at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116) at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120) at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111) at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:63) at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:747) at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:682) at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:599) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509) at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:745) 2025-06-30 10:41:24.514 [main] INFO org.springframework.scheduling.quartz.SchedulerFactoryBean - Shutting down Quartz Scheduler 2025-06-30 10:41:25.601 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} closing ... 2025-06-30 10:41:25.616 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} closed 30-Jun-2025 10:41:25.621 严重 [main] org.apache.catalina.startup.HostConfig.deployWAR 部署 Web 应用程序 archive [/home/csp/apache-tomcat-9.0.106/webapps/csp.war] 时出错 java.lang.IllegalStateException: 启动子级时出错 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:602) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:603) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1013) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1861) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:76) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:817) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:468) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1579) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:312) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:776) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:721) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:76) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:211) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:412) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:874) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.startup.Catalina.start(Catalina.java:739) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) Caused by: org.apache.catalina.LifecycleException: 无法启动组件[StandardEngine[Catalina].StandardHost[localhost].StandardContext[/csp]] at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:406) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:179) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) ... 37 more Caused by: java.lang.IllegalStateException: Failed to execute ApplicationRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:759) at org.springframework.boot.SpringApplication.lambda$callRunners$2(SpringApplication.java:746) at org.springframework.boot.SpringApplication$$Lambda$1079/1133797119.accept(Unknown Source) at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) at java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:352) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418) at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:744) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:175) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:155) at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:97) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4491) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) ... 38 more Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1597) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1383) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1366) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1093) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:421) at org.springframework.data.redis.core.RedisConnectionUtils.fetchConnection(RedisConnectionUtils.java:193) at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:144) at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:105) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211) at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) at org.springframework.data.redis.core.RedisTemplate.keys(RedisTemplate.java:896) at com.sine.csp.common.boot.RedisCleanService.run(RedisCleanService.java:27) at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:756) ... 56 more Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:109) at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1595) ... 68 more Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 127.0.0.1:6379 at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78) at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56) at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:330) at io.lettuce.core.RedisClient.connect(RedisClient.java:216) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:115) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider$$Lambda$1084/1822563181.get(Unknown Source) at java.util.Optional.orElseGet(Optional.java:267) at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:115) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$null$0(LettucePoolingConnectionProvider.java:97) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider$$Lambda$1082/1664936139.get(Unknown Source) at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:211) at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:201) at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:70) at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:571) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:298) at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:223) at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:122) at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:117) at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:103) ... 69 more Caused by: io.lettuce.core.RedisCommandExecutionException: NOAUTH HELLO must be called with the client already authenticated, otherwise the HELLO AUTH <user> <pass> option can be used to authenticate the client and select the RESP protocol version at the same time at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147) at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116) at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120) at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111) at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:63) at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:747) at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:682) at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:599) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:800) at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:509) at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:407) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:745) 30-Jun-2025 10:41:25.637 信息 [main] org.apache.catalina.startup.HostConfig.deployWAR web应用程序存档文件[/home/csp/apache-tomcat-9.0.106/webapps/csp.war]的部署已在[17,181]ms内完成 30-Jun-2025 10:41:25.637 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/home/csp/apache-tomcat-9.0.106/webapps/ROOT] 30-Jun-2025 10:41:25.659 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/home/csp/apache-tomcat-9.0.106/webapps/ROOT]的部署已在[22]毫秒内完成 30-Jun-2025 10:41:25.659 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/home/csp/apache-tomcat-9.0.106/webapps/docs] 30-Jun-2025 10:41:25.672 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/home/csp/apache-tomcat-9.0.106/webapps/docs]的部署已在[12]毫秒内完成 30-Jun-2025 10:41:25.672 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/home/csp/apache-tomcat-9.0.106/webapps/examples] 30-Jun-2025 10:41:25.770 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/home/csp/apache-tomcat-9.0.106/webapps/examples]的部署已在[97]毫秒内完成 30-Jun-2025 10:41:25.770 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/home/csp/apache-tomcat-9.0.106/webapps/host-manager] 30-Jun-2025 10:41:25.782 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/home/csp/apache-tomcat-9.0.106/webapps/host-manager]的部署已在[12]毫秒内完成 30-Jun-2025 10:41:25.783 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [/home/csp/apache-tomcat-9.0.106/webapps/manager] 30-Jun-2025 10:41:25.805 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[/home/csp/apache-tomcat-9.0.106/webapps/manager]的部署已在[23]毫秒内完成 30-Jun-2025 10:41:25.809 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"] 30-Jun-2025 10:41:25.836 信息 [main] org.apache.catalina.startup.Catalina.start [17417]毫秒后服务器启动 30-Jun-2025 10:41:29.190 警告 [http-nio-8080-exec-3] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [csp] 注册了JDBC驱动程序 [com.alibaba.druid.proxy.DruidDriver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 30-Jun-2025 10:41:29.191 警告 [http-nio-8080-exec-3] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc Web应用程序 [csp] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。 为防止内存泄漏,JDBC驱动程序已被强制取消注册。 30-Jun-2025 10:41:29.193 警告 [http-nio-8080-exec-3] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads Web应用程序[csp]似乎启动了一个为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪:[ java.lang.Object.wait(Native Method) java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:91) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:745)] 30-Jun-2025 10:41:29.194 严重 [http-nio-8080-exec-3] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks web应用程序[csp]创建了一个ThreadLocal,其键类型为[org.springframework.boot.SpringBootExceptionHandler.LoggedExceptionHandlerThreadLocal](值为[org.springframework.boot.SpringBootExceptionHandler$LoggedExceptionHandlerThreadLocal@284f8fa0]),值类型为[org.springframework.boot.SpringBootExceptionHandler](值为[org.springframework.boot.SpringBootExceptionHandler@4a632f7c),但在停止web应用程序时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏 30-Jun-2025 10:41:29.194 严重 [http-nio-8080-exec-3] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks web应用程序[csp]创建了一个ThreadLocal,其键类型为[java.lang.ThreadLocal](值为[java.lang.ThreadLocal@40ba36e7]),值类型为[io.netty.util.internal.InternalThreadLocalMap](值为[io.netty.util.internal.InternalThreadLocalMap@6ad179a0),但在停止web应用程序时未能将其删除。线程将随着时间的推移而更新,以尝试避免可能的内存泄漏 30-Jun-2025 10:41:29.995 信息 [mysql-cj-abandoned-connection-cleanup] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。 java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。 at org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading(WebappClassLoaderBase.java:1374) at org.apache.catalina.loader.WebappClassLoaderBase.getResource(WebappClassLoaderBase.java:997) at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.checkThreadContextClassLoader(AbandonedConnectionCleanupThread.java:123) at com.mysql.cj.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:90) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) 30-Jun-2025 10:41:32.509 信息 [http-nio-8080-exec-3] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间JSP编译时间。
最新发布
07-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值