Пострадавшие от тайфуна Ликима, во многих местах прошли проливные дожди. Вы не можете выходить на улицу, чтобы играть и учиться вместе по выходным. Давайте начнем с самой базовой конфигурации, а затем представим расширенные функции журнала асинхронного вывода. Если вы хотите увидеть только ту часть, в которой журналы асинхронного вывода улучшают производительность, прокрутите статью немного вниз.
Прочитав эту статью, вы узнаете
- 1. Лог выводится в файл и на основе
LEVEL
Уровни сохраняют категории журналов в разные файлы - 2. Уменьшите диск, выводя журналы асинхронно
IO
Улучшить производительность - 3. Принцип асинхронного вывода журнала
Файл конфигурации logback-spring.xml
SpringBoot
Проект поставляется сlogback
иslf4j
Зависимость, поэтому основное внимание уделяется написанию файлов конфигурации, тому, какие зависимости необходимо ввести, и нам не нужно управлять конфликтами зависимостей журналов.logback
Фреймы загружаются по умолчаниюclasspath
названный подlogback-spring
илиlogback
конфигурационный файл. Хранение всех журналов в одном файле Размер файла также увеличивается с запуском приложения, и решить проблему непросто.error
Журналы отделены от других журналов, а журналы разных уровней записываются и хранятся в соответствии с периодами времени.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<property resource="logback.properties"/>
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
<!--获取比info级别高(包括info级别)但除error级别的日志-->
<appender name="INFO-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${LOG_INFO_HOME}//%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${LOG_ERROR_HOME}//%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG" />
<appender-ref ref="INFO-LOG" />
<appender-ref ref="ERROR-LOG" />
</root>
</configuration>
Часть описания ярлыка
-
<root>
Метка, обязательная метка, используемая для указания самого базового уровня вывода журнала.-
<appender-ref>
метка, добавитьappend
-
-
<append>
метка, используя метку для указания политики сбора журналов.-
name
назначение атрибутаappender
название -
class
Атрибут указывает стратегию вывода.Обычно существует два типа: вывод на консоль и вывод в файл.Вывод в файл предназначен для сохранения журнала.ConsoleAppender
вывод лога в консоль
-
-
<filter>
метка, используя метку для указания политики фильтрации-
<level>
Метка указывает тип фильтрации
-
-
<encoder>
ярлык, используйте<pattern>
Тег указывает формат вывода журнала. -
<rollingPolicy>
Теги определяют политики сбора, такие как сбор на основе времени.-
<fileNamePattern>
Метка указывает место, где сохраняется сгенерированный журнал. Благодаря этой конфигурации цель классификации и разделения журналов мобильных телефонов была достигнута.
-
расширенные функции logback асинхронный вывод журнала
Предыдущий метод настройки журнала основан на синхронизации, и каждый раз, когда журнал выводится в файл, выполняется дисковый ввод-вывод. Метод асинхронной записи журнала используется для предотвращения дискового ввода-вывода при записи этого журнала, блокирования потоков и ненужной потери производительности. Способ асинхронного вывода логов очень прост, добавьте лог на основе асинхронной записиappender
, и укажите на ранее настроенныйappender
Просто
<!-- 异步输出 -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="INFO-LOG"/>
</appender>
<appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>256</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="ERROR-LOG"/>
</appender>
Тест производительности журнала асинхронного вывода
Так как производительность может быть улучшена, необходимо провести тестовое сравнение, во сколько раз можно улучшить производительность синхронных и асинхронных журналов вывода?
серверное оборудование
-
CPU
Шесть ядер - Память 8G
инструменты для тестирования
Apache Jmeter
Журнал синхронного вывода
- Количество потоков: 100
-
Ramp-Up Loop
(Это можно понимать как время, необходимое для запуска потока): 0 Можно понять, что 100 потоков включены одновременно - Результаты тестаСосредоточьтесь на метриках
Throughput【TPS】
Пропускная способность: количество запросов, обработанных системой в единицу времени, в журнале выходных данных синхронизации.TPS
за44.2/sec
Журнал асинхронного вывода
- Количество потоков 100
-
Ramp-Up Loop
: 0 - Результаты теста
TPS
за497.5/sec,Более чем в 10 раз выше производительность! ! !
Принцип асинхронного вывода журнала
отlogback
под рамойLogger.info
способ начать трассировку. Полный путь вызова метода показан на следующем рисунке:
ch.qos.logback.classic
под пакетомAsyncAppenderBase
в классеappend
метод, см. исходный код этого метода:
protected void append(E eventObject) {
if(!this.isQueueBelowDiscardingThreshold() || !this.isDiscardable(eventObject)) {
this.preprocess(eventObject);
this.put(eventObject);
}
}
Определите, нужно ли удалять журнал из-за ситуации с очередью. Если нет, поместите его в очередь блокировки. Просмотрев код, очередь блокировкиArrayBlockingQueueu
, размер по умолчанию — 256, который можно изменить в файле конфигурации.Logger.info(...)
прибытьappend(...)
Все кончено, просто запихните лог в очередь на блокировку, а потом продолжайте выполнятьLogger.info(...)
следующее утверждение.
существуетAsyncAppenderBase
класс определяетWorker
нить,run
Ключевая часть кода в методе выглядит следующим образом:
E e = parent.blockingQueue.take();
aai.appendLoopOnAppenders(e);
Возьмите лог из очереди на блокировку и позвонитеAppenderAttachableImpl
в классеappendLoopOnAppenders
метод поддержанияAppend
список.Worker
Процесс вызова метода в потоке в основном выглядит следующим образом:
encode
иwrite
метод, предыдущий метод будет основан на файле конфигурацииencode
Указанный метод преобразуется в байт-код, а последний метод записывает преобразованный байт-код в файл. Таким образом, запись файла выполняется путем запуска нового потока, основной поток бросает журнал в очередь блокировки, а затем занимается другими делами.Наконец прикрепил:Полный код проекта
======================= Обновление от 02.09.2019 ===================== знак равно Результаты теста загрязнены, количество повторений мало, а количество выборок мало.После повторного тестирования разница между синхронным выводом логбека и TPS асинхронного вывода особо не очевидна.Прикреплено:Отчет о тестировании производительности. Но есть еще сокращение времени