博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
异步打印日志的一点事
阅读量:5881 次
发布时间:2019-06-19

本文共 1074 字,大约阅读时间需要 3 分钟。

点击上方关注,每天学习一个java知识点

一、前言

最近刚刚结束转岗以来的第一次双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。

来源:今天你不奋斗明天你就落后 ,

www.jianshu.com/p/900d433051e6

转载地址:http://yrpix.baihongyu.com/

你可能感兴趣的文章
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>
CSS魔法堂:Transition就这么好玩
查看>>
Golang协程与通道整理
查看>>
解决win7远程桌面连接时发生身份验证错误的方法
查看>>
C/C++ 多线程机制
查看>>
js - object.assign 以及浅、深拷贝
查看>>
python mysql Connect Pool mysql连接池 (201
查看>>
Boost在vs2010下的配置
查看>>
一起谈.NET技术,ASP.NET伪静态的实现及伪静态的意义
查看>>
20款绝佳的HTML5应用程序示例
查看>>
string::c_str()、string::c_data()及string与char *的正确转换
查看>>
11G数据的hive初测试
查看>>
如何使用Core Text计算一段文本绘制在屏幕上之后的高度
查看>>
==和equals区别
查看>>
2010技术应用计划
查看>>
XML 节点类型
查看>>
驯服 Tiger: 并发集合 超越 Map、Collection、List 和 Set
查看>>
Winform开发框架之权限管理系统改进的经验总结(3)-系统登录黑白名单的实现...
查看>>
LeetCode – LRU Cache (Java)
查看>>
JavaScript高级程序设计--对象,数组(栈方法,队列方法,重排序方法,迭代方法)...
查看>>