前语

工作是这样的: 当咱们运用报错并进行记载日志的时候,发现体系响应速度显着变慢,所以咱们排查到或许是由于记载日志时降低了体系功用吞吐量

所以咱们尝试将日志添加缓存设置并选用异步日志

来缓解而且选用异步记载的办法来进步体系功用。

为此咱们也对主流日志结构的装备做了如下整理。

给日志添加缓存

给日志添加缓存的首要意图是进步功用和削减磁盘I/O操作。缓存能够帮助解决以下问题:

优点:

  • 功用优化:频频地将日志写入磁盘或许会对运用程序的功用发生负面影响,由于磁盘I/O操作通常比内存操作要慢得多。经过在缓冲区中暂存日志,Log4j2能够将多个日志记载合并到一次磁盘写入操作中。这样,在缓冲区满时,日志会一次性写入磁盘,然后削减了磁盘I/O操作的频率,进步了功用。

  • 降低磁盘运用率:将日志频频地写入磁盘或许会导致磁盘空间快速耗尽,尤其是在大量日志生成的情况下。运用缓存能够削减磁盘运用率,由于缓冲区答应您将多个日志记载合并到一次磁盘写入操作中。这样,磁盘上的日志文件能够更紧凑地存储,节省磁盘空间。

  • 削减磁盘碎片:频频地将日志写入磁盘或许会导致磁盘碎片,然后降低磁盘功用。经过运用缓存,您能够削减碎片发生的或许性,由于日志记载将在缓冲区中组合,然后一次性写入磁盘。

缺陷:

  • 运用缓存的缺陷是或许会导致在运用程序溃散或意外终止时丢掉没有写入磁盘的日志。

因而,在完结日志缓存时,需求在功用和日志数据安全性之间找到平衡。比如能够经过调整缓冲区巨细和设置元素来完结这一平衡。请注意,在运用程序正常退出时,保证正确关闭Log4j2以将缓冲区中剩下的日志写入磁盘。

log4j的缓存设置

在Log4j中,日志缓存首要经过FileAppender的bufferedIO和bufferSize特点来装备。bufferedIO特点用于启用或禁用缓存,bufferSize特点用于设置缓冲区巨细。

以下是一个Log4j(1.x)装备文件(log4j.properties)示例,展现了怎么为FileAppender设置缓存:

log4j.rootLogger=INFO, file
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=logs/app.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %msg%n
log4j.appender.file.bufferedIO=true
log4j.appender.file.bufferSize=8192

在这个比如中,bufferedIO设置为true以启用缓存,bufferSize设置为8192字节,即8KB。

log4j2的缓存设置

在Log4j2中,日志缓存经过在FileAppender中添加元素并设置bufferSize特点来完结。

以下是一个Log4j2(2.x)装备文件(log4j2.xml)示例,展现了怎么为FileAppender设置缓存:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <Appenders>
        <File name="FileAppender" fileName="logs/app.log">
            <PatternLayout>
                <Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %msg%n</Pattern>
            </PatternLayout>
            <BufferedIO bufferSize="8192"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="FileAppender"/>
        </Root>
    </Loggers>
</Configuration>

在这个比如中,bufferSize设置为8192字节,即8KB。

总归,尽管Log4j和Log4j2都支撑日志缓存,但它们的装备办法略有不同。在Log4j中,您需求在log4j.properties文件中设置bufferedIO和bufferSize特点;而在Log4j2中,您需求在log4j2.xml文件中运用元素并设置bufferSize特点。

logback的缓存设置

Logback供给了相似的缓存功用,经过ImmediateFlush特点装备。ImmediateFlush特点决定是否立行将日志刷新到磁盘。当ImmediateFlush设置为false时,Logback将在内部缓存日志,直到缓冲区满,然后再将日志写入磁盘。这有助于削减磁盘I/O操作,进步功用。

以下是一个Logback装备文件(logback.xml)示例,展现了怎么设置缓存:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logs/app.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <immediateFlush>false</immediateFlush>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

在这个比如中,元素被设置为false,这意味着Logback将在内部缓存日志,直到缓冲区满,然后再将日志写入磁盘。

请注意,将设置为false或许会在运用程序溃散或意外终止时导致没有写入磁盘的日志丢掉。因而,在完结日志缓存时,需求在功用和日志数据安全性之间找到平衡。您能够依据需求将设置为true,以保证每次写入日志时都将缓冲区刷新到磁盘。但是,这或许会影响功用,由于磁盘I/O操作通常比内存操作慢得多。

异步日志记载

异步日志记载的首要意图是将日志记载与运用程序主流程别离,以削减日志记载对运用程序功用的影响。当选用异步日志记载时,日志记载操作通常在一个独自的线程或线程池中履行,这样运用程序主线程能够在不等候日志记载完结的情况下继续履行。

优点:

  • 降低功用开支:由于日志记载操作在独自的线程或线程池中履行,运用程序主线程能够不受阻塞地继续履行。这能够降低日志记载对运用程序功用的影响,特别是在高负载情况下。

  • 进步吞吐量:异步日志记载能够进步运用程序的吞吐量,由于主线程无需等候日志记载操作完结。这样,运用程序能够更快地处理请求和履行任务。

  • 缓解磁盘I/O压力:异步日志记载能够将多个日志记载请求批量处理,然后削减磁盘I/O操作。这有助于减轻磁盘I/O压力,并进步整体功用。

缺陷:

  • 例如,在运用程序溃散或意外终止时,异步日志记载或许导致没有处理的日志记载丢掉。

  • 此外,异步日志记载或许会添加内存占用,由于日志记载请求需求在内存中排队等候处理。

Log4j2:

在 Log4j2 中设置异步日志记载十分简单。首先,您需求在装备文件(例如 log4j2.xml)中添加一个名为 或 的元素。这些元素答应您将指定的日志记载器装备为异步模式。例如:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <AsyncRoot level="info">
            <AppenderRef ref="Console"/>
        </AsyncRoot>
    </Loggers>
</Configuration>

在这个示例中,咱们运用 元素装备了根日志记载器,使其异步记载日志,并将其等级设置为 “info”。日志输出将被写入控制台

Logback:

Logback 没有内置的异步日志记载支撑,但能够经过添加 logback-classic 依赖项中的 ch.qos.logback.classic.AsyncAppender 来完结。以下是一个 logback.xml 装备文件示例:

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="STDOUT" />
    </appender>
    <root level="info">
        <appender-ref ref="ASYNC" />
    </root>
</configuration>

在这个示例中,咱们运用 ch.qos.logback.classic.AsyncAppender 类创建了一个名为 “ASYNC” 的异步 appender,并将其装备为运用名为 “STDOUT” 的控制台 appender。根日志记载器将记载 “info” 等级的日志并运用 “ASYNC” appender。

Log4j 1.x:

Log4j 1.x 没有内置的异步日志记载支撑,但能够经过运用 Apache Extras 的 org.apache.log4j.AsyncAppender 完结。首先,您需求在项目中添加 Apache Extras for Log4j 的依赖项。然后,您能够在装备文件(例如 log4j.properties)中装备异步 appender,如下所示:

log4j.rootLogger=info, ASYNC
log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d{HH:mm:ss.SSS} [%t] %-5p %c{1} - %m%n
log4j.appender.ASYNC=org.apache.log4j.AsyncAppender
log4j.appender.ASYNC.appender-ref=STDOUT

在这个示例中,咱们运用 org.apache.log4j.AsyncAppender 类创建了一个名为 “ASYNC” 的异步 appender,并将其装备为运用名为 “STDOUT” 的控制台 appender。根日志记载器将记载 “info” 等级的日志并运用 “ASYNC” appender。

总结一下,这些示例演示了怎么在 Log4j2、Logback 和 Log4j 1.x 中设置异步日志记载。在实际运用中,依据项目需求和日志结构挑选适宜的异步日志记载设置。异步日志记载能够进步运用程序功用,但需求权衡内存占用和日志丢掉危险。

各个日志组件的功用优势

Log4j(1.x)

Log4j是Apache供给的一个前期日志结构。尽管它现已过期并被Log4j2取代,但它仍然在许多现有项目中运用。它供给了根本的缓存功用,能够经过bufferedIO和bufferSize特点设置。这有助于削减磁盘I/O操作并进步功用。但是,与Log4j2和Logback比较,Log4j的功用较低。

Log4j2(2.x)

Log4j2是Log4j的继任者,功用显着优于Log4j和Logback。Log4j2的缓存完结利用了元素,答运用户指定缓冲区巨细。Log4j2的一个显著优势是其异步日志记载功用。异步记载能够显著降低日志记载对运用程序功用的影响。异步Appender能够与缓存功用结合运用,进一步进步功用。总的来说,Log4j2在功用方面具有很大优势。

Logback

Logback是SLF4J项意图完结之一,作为Log4j的代替方案。Logback的功用优于Log4j,但略逊于Log4j2。Logback的缓存功用经过特点完结,答运用户挑选是否立行将日志刷新到磁盘。尽管这种办法不如Log4j2的异步日志记载和缓存功用灵活,但它仍然能够在一定程度上进步功用。

功用排名

graph TD
    Log4j --> Logback
    Logback --> Log4j2

小结

  1. Log4j 1.x 现已过期,不再保护。因而,建议运用 Log4j2 或 Logback,由于它们供给了更先进的功用和更好的功用。
  2. Log4j2在功用方面具有显着优势,特别是在缓存和异步日志记载方面。Logback的功用优于Log4j,但略逊于Log4j2。Log4j的功用相对较低,但它仍然在许多现有项目中运用。在考虑功用时,引荐运用Log4j2或Logback作为日志结构。
  3. 运用缓存的缺陷是或许会导致在运用程序溃散或意外终止时丢掉没有写入磁盘的日志,在完结日志缓存时,需求在功用和日志数据安全性之间找到平衡
  4. 异步日志记载的首要作用是经过将日志记载操作与运用程序主流程别离,降低功用开支、进步吞吐量和缓解磁盘I/O压力。但是,也或许添加日志丢掉的危险和内存占用。在实际运用中,需求依据运用程序的功用需求和日志记载负载来权衡异步日志记载的优缺陷。