异步打印日志的一点事
来源:互联网 发布:网络用语 胡萝卜 编辑:程序博客网 时间:2024/06/06 06:40
异步打印日志的一点事
一、前言
最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步打日志会阻塞调用打日志的线程,而打日志本身是需要写磁盘的,所以会造成rt增加。异步日志就是为了解决这个问题。
二、日志打印模型
- 同步日志模型
如上图,多个业务线程打印日志时候要等把内容写入磁盘后才会返回,所以打日志的rt就是写入磁盘的耗时。
- 异步日志模型
如上图多个业务线程打印日志时候是把打印任务放入内存队列后就直接返回了,而具体打印日志是有日志系统的一个日志线程去队列里面获取然后执行,可见这种打印rt就是写入内存队列的耗时。
三、关于异步日志的一些事
- 异步日志设置
对于logback来说异步日志里面的队列是一个有界ArrayBlockingQueue,其中queueSize是队列大小,taskLogAppender是引用的普通同步日志
discardingThreshold是一个阈值,通过下面代码看他的作用:
当队列的剩余容量小于这个阈值并且当前日志level TRACE, DEBUG or INFO ,则丢弃这些日志。
在压测时候代码配置如上,也就是配置了异步日志,但是还是出现了线程阻塞在打日志的地方了,经查看是阻塞到了日志队列ArrayBlockingQueue的put方法:
可知put方法在队列满时候会挂起当前线程。那么如何解那?
上面介绍了discardingThreshold,可知本文设置为0说明永远不会丢弃日志level TRACE, DEBUG or INFO的日志,只要discardingThreshold>0则当队列快满时候level TRACE, DEBUG or INFO的日志就会丢弃掉,这个貌似可以解决问题。但是如果打印的是warn级别的日志那?还是会在put的时候阻塞。
通过看代码发现最终写日志时候有个判断:
如果设置了neverBlock=true则写日志队列时候会调用ArrayBlockingQueue对的offer方法而不是put,而offer是非阻塞的:
可知如果队列满则直接返回,而不是被挂起当前线程。
所以配置异步appender时候如下:
四 、总结
在高并发低延迟要求的系统里面不重要的日志可以设置为异步并且要注意设置队列满则丢弃策略,防止业务线程被挂起从而影响rt
- 异步打印日志的一点事
- 异步日志打印的一些事
- 异步打印日志的配置
- 关于嵌入式系统日志打印的一点建议
- log4j2日志异步打印 (3)
- 一点异步Socket的总结
- 异步io的一点理解
- 打印日志的写法
- log日志的打印
- 打印日志的时机
- 关于“日志”的一点心得
- 关于“日志”的一点想法
- 写日志的一点想法
- 一个高效的异步日志
- brit打印日志的问题
- logSvr的日志打印函数
- 【J2ME】J2ME的日志打印
- 日志打印位置的选择
- bug宝典之JAVA篇 Dynamic Web Module 3.0 requires Java 1.6 or newer.
- C++ 释放指针操作
- 超级表格的评论功能你会使用吗?
- Greenplum merge insert 用法与性能 (insert on conflict)
- Oracle表数据delete后恢复(救命用的)
- 异步打印日志的一点事
- nineoldandroids-2.4.0.jar冲突解决方式
- JavaScript中的类型与变量
- mycat安装笔记
- Java位运算理解和应用
- DSP TMS320FF28335程序从FLASH中拷贝到RAM中的两种方法及FLASH烧写方法
- Qt开发环境搭建和下载地址
- mysql中模糊查询的四种用法介绍
- 问题: Header Search Paths 与 User Header Search Paths 的区别