异步日志记录

问题描述 投票:0回答:5

现在在我的应用程序中,在某些时候,我们正在将一些沉重的东西记录到日志文件中。

基本上只用于日志记录,我们正在创建可用数据的 JSON,然后登录到日志文件中。这是以 JSON 格式记录数据的业务需求。

现在从可用数据创建 JSON 然后记录到 FILE 会花费大量时间并影响原始请求返回时间。 现在的想法是改善这种情况。

我们讨论的其中一件事是使用创建线程池

Executors.newSingleThreadExecutor() 

在我们的代码中,然后将任务提交给它,它将数据转换为 JSON 并进行后续记录。

这是一个好的方法吗?当我们管理线程池本身时,它会产生一些问题吗?

如果有人能分享更好的解决方案,我将不胜感激。 以某种方式为此使用 Log4j。我尝试使用 AsyncAppender 但没有达到任何预期的结果。

我们正在使用 EJB 3、JBoss 5.0、Log4j 和 Java6。

java asynchronous logging log4j jboss5.x
5个回答
10
投票

我相信您在使用单独的线程池进行日志记录方面走在正确的轨道上。在很多产品中,您会看到异步日志记录功能。使用与请求线程不同的线程累积日志并将其推送到日志文件。特别是在生产环境中,有数百万个传入请求,您的响应时间需要少于几秒钟。您无法承受诸如日志记录之类的任何东西来减慢系统速度。所以使用的方法是在内存缓冲区中添加日志,并以合理大小的块异步推送它们。

使用线程池进行日志记录时的注意事项 由于多个线程将处理日志文件和内存日志缓冲区,因此您需要注意日志记录。您需要在 FIFO 类型的缓冲区中添加日志,以确保日志打印在按时间戳排序的日志文件中。还要确保文件访问是同步的,你不会遇到日志文件完全颠倒或搞砸的情况。


7
投票

看看 Logback,AsyncAppender 它已经提供了单独的线程池、队列等,并且很容易配置,它几乎和你做的一样,但让你免于重新发明轮子。


3
投票

是否考虑使用 MongoDB 进行日志记录

  1. MongoDB 插入可以异步完成。如果日志记录缓慢、停滞,人们不希望用户体验停滞不前 或向下。 MongoDB 提供的能力 触发插入日志集合而不是等待响应代码。 (如果一个 想要一个响应,一个调用 getLastError()——我们会在这里跳过它。)
  2. 旧日志数据自动 LRU 淘汰。通过使用上限集合, 我们为日志预分配空间,一旦空间满了,日志就会换行 并重复使用指定的空间。没有填满磁盘的风险 日志信息过多,无需写日志归档 / 删除脚本。
  3. 解决问题的速度足够快。首先,MongoDB 速度非常快 一般,对于这样的问题足够快。其次,当使用 上限集合,自动保留插入顺序:我们 不需要在时间戳上创建索引。这使事情甚至 更快,并且很重要,因为日志记录用例具有非常 与读取相比,写入次数较多(与大多数数据库相反 问题)。
  4. 面向文档/JSON 是一种很好的日志信息格式。非常灵活和“无模式”,在某种意义上我们可以投入额外的 任何时候我们想要的领域。


0
投票

您也可以尝试 CoralLog 使用中断模式异步记录数据。这样,您在记录器线程中花费的时间最少,并且所有艰苦的工作都传递给执行实际文件 I/O 的线程。它还提供内存映射文件来加速消费者线程并减少队列争用。

免责声明: 我是 CoralLog 的开发者之一

© www.soinside.com 2019 - 2024. All rights reserved.