Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of Java Log performance

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "Java log performance instance analysis". In daily operation, I believe many people have doubts about Java log performance instance analysis. The editor consulted all kinds of data and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts of "Java log performance instance analysis". Next, please follow the editor to study!

When it comes to Java logs, everyone will certainly say that we should choose a reasonable log level and control the contents of the log reasonably, but this is only the first step in the long march. Even if some DEBUG-level logs are not output to a file in a production environment, it may incur significant overhead. Leaving aside the overhead of judgment and method calls, there is a set of comparisons in the performance documentation for Log4J 2.x:

Logger.debug ("Entry number:" + I + "is" + String.valueOf (entry [I])); logger.debug ("Entry number: {} is {}", I, entry [I])

The above two statements have the same effect on log output, but their overhead is not the same when closing the DEBUG log. The main impact is on string conversion and string concatenation, where variables are converted to strings and concatenated whether they are valid or not, while the latter only performs these operations when needed. The official test conclusion of Log4J is that the two can differ by two orders of magnitude in performance. Imagine how much resources can be saved if ToStringBuilder is used in the toString () method of an object to reflect dozens of properties.

As a result, some companies that are still using Log4J 1.x or Apache Commons Logging (they do not support the writing of the {} template) have coding specifications that require additional judgments before a certain level of log output, such as DEBUG and INFO:

If (logger.isDebugEnabled ()) {logger.debug ("Entry number:" + I + "is" + String.valueOf (entry [I]));}

In addition to the log level and log messages, there is usually some other information in the log, such as date, thread name, class information, MDC variable, and so on. According to the Takipi test, if class is added to the log, the performance will drop sharply, and the throughput will drop by about 60% compared to the default configuration of LogBack. If you must print the class information, consider naming the Logger with the class name.

In a distributed system, a request may pass through many different subsystems, so it is best to generate a UUID attached to the request, and each subsystem will put the UUID in the MDC when printing the log, so as to facilitate subsequent query of related logs. "The Ultimate Guide: 5 Methods For Debugging Production Servers At Scale" gives a lot of advice on how to debug in a production environment, several of which are about logging, which is one of them. Another suggestion is to record all uncaptured logs. In fact, it is expensive to throw an exception, and recording an exception also brings some overhead. The main reason is that the fillInStackTrace method of the Throwable class is synchronized by default:

Public synchronized native Throwable fillInStackTrace ()

Generally speaking, logger.error will hit an abnormal stack. If there is a certain requirement for throughput, you can consider overriding this method when the situation runs, remove synchronized native, and return the instance itself directly.

After chatting about the contents of the log, let's take a look at Appender. In Java, everyone will think of NIO when talking about IO operations. When it comes to JDK 7 and AIO, at least they all know that read and write add a Buffer, and so do logs. Synchronous Appender is somewhat inadequate in systems with high concurrency and high traffic, so it's time to use AsyncAppender, and also use LogBack:

Under the concurrency of 10 threads and outputting a 200-character INFO log, the maximum throughput of AsyncAppender is 3.7 times that of FileAppender. Queue length can also have an impact on performance without losing logs and using AsyncAppender as well.

If you use Log4J 2.x, then in addition to AsyncAppender, you can also consider the higher performance of asynchronous Logger, because the underlying use of Disruptor, no lock overhead, the performance is even more amazing. According to the official test of Log4J 2.x, Log4J 2.x is also used:

Under 64 threads, asynchronous Logger is 12 times faster than asynchronous Appender and 68 times faster than synchronous Logger.

It is also asynchronous, and there are differences between different libraries:

Under the same hardware environment, Log4J 2.x using asynchronous Logger will be 12 times faster than LogBack's AsyncAppender and 19 times faster than Log4J 1.x 's asynchronous Appender.

The asynchronous Logger of Log4J 2.x is powerful, but it also has different sounds. It just looks elegant and can only be used as a toy. On this issue, it is left to the reader to think for himself.

If you must use synchronized Appender, consider using ConsoleAppender and then redirecting the STDOUT to a file, which will result in a performance improvement of about 10%.

Most production systems are deployed in clusters, so use tools such as Logstash to collect logs distributed on different servers. In many cases, multiple instances will be deployed on a single machine to make full use of server resources. In this case, do not crave the convenience of log monitoring or log query, and write the logs of multiple instances to the same log file. Although LogBack provides prudent mode, which allows multiple JVM to write logs to the same file, this method also has an impact on performance, which will reduce performance by about 10%.

If you have a large number of write requirements for the same log file, you can consider splitting the log into different files. One of the ways is to add multiple Appender, modify the code at the same time, and use different Logger for different situations. LogBack provides SiftingAppender, which can split logs directly according to the contents of MDC. Jetty tutorials have examples of splitting logs according to host. According to Takipi tests, the performance of SiftingAppender will improve with the growth of the number of split files. When split into 4 files, the throughput of SiftingAppender under 10 concurrency is about 3 times that of FileAppender.

At this point, the study on "Java log performance instance analysis" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report