zoukankan      html  css  js  c++  java
  • logback日志异步打印

    最近碰到一个问题:客户的服务器程序偶尔出现请求响应过慢的情况,通过查看日志发现RSA验证签名的代码执行超过20秒,而正常情况下只需要16毫秒

    RSA证书是服务器启动就加载好的,不存在读文件慢的问题。看了一下那几行代码,最有嫌疑的就是logback日志打印的代码了。

    查看了生产日志配置,logback.xml里配置为,每月生成一个文件夹,当月的日志文件都在同一文件夹下,比如201901文件夹下是2019年1月的所有日志文件。每个文件配置为*.log.zip后缀,大小为10MB,也就是说10MB为大小分隔文件。日志打印类配置的是RollingFileAppender

    2019-1-30那一天,2019年1月文件夹下已经产生了5000多个日志文件,平均每天167个日志文件。

    所以怀疑是日志文件太多,索引文件的时间太长导致代码执行变慢,也就是说,要这样怀疑的话,那就有一个前提:日志打印是同步的,调用打印日志的那行代码执行完了写入文件后,才会继续向下执行业务代码。

    我问了好几个同事,都给我说日志打印是异步执行的,只有一个朋友说是同步的。我们都会以为打印日志写文件比较消耗时间,日志框架应该不会同步去写文件吧。然而事实却是如果不配置异步打印方式的话,就是以同步方式进行的日志打印的。

    断点跟进代码发现是同步执行日志写入文件的,只有当配置的appender是AsyncAppender时,日志打印才是按照异步方式打印的。

    下面是同步打印日志的情况:

    logback.xml配置:

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        ......
    </appender>
    
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
    </root>

    执行代码:

    LogWork.debug("111111111111");
    System.out.println("2222222222222");

    运行结果:

    可以看到,执行结果是先把日志框架的日志打印执行完,再执行后面的业务代码的。所以是同步的。

    下面是配置异步打印日志类的方法:

    异步打印日志类AsyncAppender需要引用一个其他的日志打印类,ASYNC只需要把需要打印的日志写入定义好的缓存队列里,然后开启一个守护线程去队列里取得日志调用CONSOLE日志打印器去写入文件。这样日志打印就是异步进行的了。

    logback.xml配置:

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        ......
    </appender>
    
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>100</queueSize>
        <neverBlock>true</neverBlock>
        <appender-ref ref="CONSOLE"/>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="ASYNC"/>
    </root>

    执行代码:

    LogWork.debug("111111111111");
    System.out.println("2222222222222");

    运行结果:

    运行结果说明,调用日志框架打印的代码执行后只是把要打印的日志放入缓存队列,然后就继续向下执行后面的代码,所以才先打印了后面的222222,之后才打印111111。说明是现在经过配置,日志打印异步工作的。

    因文章开头的问题引出了对日志打印同步性的问题,所以研究了一番,不过最终也没有和遇到的问题联系起来,因为就算知道了日志是同步打印的,也没法解释为什么偶尔出现几分钟代码执行特别慢。证据不充分,所以没法给出结论。

  • 相关阅读:
    求助:可以使用任何编程工具做成一个控件或组件,使得在VB中能调用并得到摄像头的参数及图片。
    作为软件工程师,你必须知道的20个常识
    继续C#开发or转做产品
    65行 JavaScript 代码实现 Flappy Bird 游戏
    自上而下的软件开发和自下而上的软件开发
    没有发布过产品的程序员不知道什么是真正的软件
    20个数据库设计的最佳实践
    59条搞笑但却真实无比的编程语录
    自己动手跟着Jwt标准实现Jwt
    Gitlab-Runner基础教程
  • 原文地址:https://www.cnblogs.com/burthughes/p/logback_asynchronized.html
Copyright © 2011-2022 走看看