14

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

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

现在从可用数据创建 JSON 然后记录到 FILE 需要大量时间并影响原始请求返回时间。现在的想法是改善网站。

我们讨论过的一件事是使用

Executors.newSingleThreadExecutor() 

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

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

如果有人可以分享更好的解决方案,我将不胜感激。以某种方式为此使用 Log4j。我尝试使用 AsyncAppender 但没有达到任何预期的结果。我们正在使用 EJB 3、Jboss 5.0、Log4j、java6。

4

5 回答 5

9

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

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

于 2013-06-10T07:07:58.937 回答
7

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

于 2013-06-10T07:11:02.510 回答
3

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

  1. MongoDB 插入可以异步完成。如果日志记录缓慢、停滞或下降,人们不希望用户体验陷入停顿。MongoDB 提供了在日志集合中触发插入而不等待响应代码的能力。(如果想得到响应,调用 getLastError() ——我们会在这里跳过。)
  2. 旧日志数据自动 LRU 出。通过使用上限集合,我们为日志预先分配空间,一旦满了,日志就会包装并重用指定的空间。没有过多日志信息填满磁盘的风险,也无需编写日志归档/删除脚本。
  3. 解决问题的速度足够快。首先,一般来说 MongoDB 非常快,对于这样的问题已经足够快了。其次,当使用有上限的集合时,插入顺序会自动保留:我们不需要在时间戳上创建索引。这使事情变得更快,并且考虑到与读取相比,日志记录用例的写入次数非常多(与大多数数据库问题相反),这一点很重要。
  4. 面向文档/JSON 是日志信息的绝佳格式。非常灵活和“无模式”,因为我们可以随时添加额外的字段。
于 2013-06-10T07:07:11.407 回答
1

还有 log4j 2: http: //logging.apache.org/log4j/2.x/manual/async.html另外阅读这篇文章为什么这么快:http ://www.grobmeier.de/log4j- 2-性能接近疯狂-20072013.html#.UzwywI9Bow4

于 2014-04-02T15:55:09.667 回答
0

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

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

于 2014-07-08T11:52:37.310 回答