zoukankan      html  css  js  c++  java
  • spring boot 2 内嵌Tomcat Stopping service [Tomcat]

    我在使用springboot时,当代码有问题时,发现控制台打印下面信息:

    Connected to the target VM, address: '127.0.0.1:42091', transport: 'socket'
    log4j:WARN No appenders could be found for logger (org.springframework.boot.devtools.settings.DevToolsSettings).
    log4j:WARN Please initialize the log4j system properly.
    log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
    
      .   ____          _            __ _ _
     /\ / ___'_ __ _ _(_)_ __  __ _    
    ( ( )\___ | '_ | '_| | '_ / _` |    
     \/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v2.0.6.RELEASE)
    
    2018-10-25 10:10:21.425  INFO 102158 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    2018-10-25 10:10:21.427  INFO 102158 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.34
    2018-10-25 10:10:21.444  INFO 102158 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
    2018-10-25 10:10:21.590  INFO 102158 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    2018-10-25 10:10:24.522  INFO 102158 --- [  restartedMain] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
    Disconnected from the target VM, address: '127.0.0.1:42091', transport: 'socket'
    
    Process finished with exit code 0
    

    WTF?没有错误信息怎么解决问题? 各种搜索,总之就是代码有问题,自己检查把...

    好吧,直接debug把

    内嵌tomcat的入口类是org.apache.catalina.core.StandardService

    //TODO 后面补上过程

    最终找到org.springframework.context.support.AbstractApplicationContext 定位方法refresh()

    if (logger.isWarnEnabled()) {
    				logger.warn("Exception encountered during context initialization - " +
    						"cancelling refresh attempt: " + ex);
    			}
    

    debug可以正常进入,然后就看到我们希望看到的 ex了

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fabricApiController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fabricTemplate': Injection of resource dependencies failed; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'fabricConfiguration': Could not bind properties to 'FabricConfiguration' : prefix=blockchain, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'blockchain.channel-peers' to java.util.List<com.smy.bc.fabric.core.configuration.FabricConfiguration$EndPoint>
    

    问题发现了,解决自己代码问题,然后重新启动,正常! 万事大吉?错,这才开始

    上面我们简单解决了问题,但是根源没有解决!
    要说解决方案把当前流行的日志体系简单说一遍
    下面整理的来源网络:
    
    常见的日志框架,注意不是具体解决方案
    
    1 Commons-logging: apache 最早提供的日志的门面接口。避免和具体的日志方案直接耦合。类似于JDBC的api接口,具体的的JDBC driver实现由各数据库提供商实现。通过统一接口解耦,不过其内部也实现了一些简单日志方案
    2 Slf4j: 全称为Simple Logging Facade for JAVA:java简单日志门面。是对不同日志框架提供的一个门面封装。可以在部署的时候不修改任何配置即可接入一种日志实现方案。和commons-loging应该有一样的初衷。
    
    常见的日志实现:
    log4j
    logback
    jdk-logging
    
    详细优缺点不是本文重点,请自行搜索。
    

    接着分析上面的问题,Commons-logging 是tomcat默认的日志系统(apache自家东西得支持),具体的日志实现,根据系统已存在日志系统选择。 简单列举以下log的实现: org.apache.commons.logging.Log | org.apache.commons.logging.impl.SimpleLog org.apache.commons.logging.impl.NoOpLog org.apache.commons.logging.impl.Log4JLogger org.apache.commons.logging.impl.SLF4JLog org.apache.commons.logging.impl.Jdk14Logger

    springboot 默认使用的是logback日志实现,问题就出现在这里了!!!common-logs并没有logback的实现!

    根据maven依赖,我们看到log4j和logback的包都被引入了,然后tomcat之能选择的是log4j,springboot使用的是logback。 log4j和logback只见缺少一个桥梁,正是缺少的这个桥梁,导致springboot只能输出logback!!!

    中间的桥梁就是下面这个依赖

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
        </dependency>
    

    这个依赖可以将log4j输出到slf4j,从而从sl4j输出。

    总结: 总结一下,已经搞明白是slf4j/common-logs <> log4j和logback的恩怨情仇

    第一种解决方式:根据日志定位问题,然后采用加法处理,增加jcl-over-slf4j,打通slf4j和common-logs通道

    第二种解决方式:解决冲突,一山不容二虎,排除掉slf4j,common-logs任意一方,spring使用slf4j,那可以排除调common-logs

    从项目优化的角度看,第二种更优,可以减少不必要的依赖。

    如果日志出现问题,那就是日志体系发生冲突了,可以参考这个思路,处理项目中日志异常问题

  • 相关阅读:
    推荐系统 蒋凡译 第一章 引言 读书笔记
    神经网络与深度学习 邱锡鹏 第5章 卷积神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第4章 前馈神经网络 读书笔记
    神经网络与深度学习 邱锡鹏 第3章 线性模型 读书笔记
    神经网络与深度学习 邱锡鹏 第2章 机器学习概述 读书笔记
    神经网络与深度学习 邱锡鹏 第1章 绪论 作业
    神经网络与深度学习 邱锡鹏 第1章 绪论 读书笔记
    算法笔记 上机训练实战指南 第13章 专题扩展 学习笔记
    算法笔记 第13章 专题扩展 学习笔记
    算法笔记 上机训练实战指南 第11章 提高篇(5)--动态规划专题 学习笔记
  • 原文地址:https://www.cnblogs.com/jtlgb/p/10288419.html
Copyright © 2011-2022 走看看