专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

高并发系统谨防被一行日志击垮

  一、同步打印日志中的坑1。1高并发场景下logback造成线程泄露
  调用logback去打印日志的时候是会加锁的,加锁的位置在:ch。qos。logback。core。OutputStreamAppenderwriteBytesprivatevoidwriteBytes(byte〔〕byteArray)throwsIOException{if(byteArray!nullbyteArray。length!0){this。lock。lock();try{this。outputStream。write(byteArray);if(this。immediateFlush){this。outputStream。flush();}}finally{this。lock。unlock();}}}
  这就意味着同一个appender的日志写是串行的,在高并发的场景下因为有锁的争用现象,所以看似很简单的一行日志,耗费的时间却不少。接下来我们在本地简单的模拟一下高并发的场景,并记录打一行日志的耗时是多少publicstaticvoidmain(String〔〕args){ExecutorServicethreadPoolnewThreadPoolExecutor(500,750,20,TimeUnit。MINUTES,newArrayBlockingQueue(1),newThreadFactoryBuilder()。setNameFormat(testlogthread)。build(),newThreadPoolExecutor。CallerRunsPolicy());for(inti0;i750;i){LoggerExecutorcommonExecutornewLoggerExecutor();threadPool。submit(commonExecutor);}}staticclassLoggerExecutorimplementsRunnable{SneakyThrowsOverridepublicvoidrun(){while(true){longstartSystem。currentTimeMillis();logger。info(loginfomessageat{},System。currentTimeMillis());longendSystem。currentTimeMillis();longtimeendstart;System。out。println(time);}}}
  需要说明的是,现实中高并发的请求应当用一个线程池向另一个线程池反复提交任务来模拟,这里我们简化了这个过程。
  上图是我记录下来的logger。info的耗时曲线,从这张统计图上可以看到,当并发量上来之后锁争用的情况加剧,仅仅是打印一行info日志就可能花费2040ms(作为对比,在我的机器上单线程打印一行日志通常是12ms),而且图上有比较明显的毛刺,打印日志的耗时超过了100ms,毛刺的原因在于OutputStream在缓存区满了后要执行刷盘动作,但是在真正大流量应用中这种毛刺是致命的,可能导致RPC框架的线程池被吃光,正常业务服务的成功率下降。所以在高并发大流量的场景下info日志的打印一定要谨慎。1。2大量异常引发性能毛刺
  在上一小节中我们提到,高并发场景下info日志要谨慎打印,一般我们只记录系统异常的日志。我们把刚才的代码片段做一个小的修改,改为调用logger。error打印日志,然后再统计下这行代码的耗时驱动代码同1。1节,所以这里省略staticclassLoggerExecutorimplementsRunnable{SneakyThrowsOverridepublicvoidrun(){while(true){longstartSystem。currentTimeMillis();logger。info(loginfomessageat{},System。currentTimeMillis());logger。error(loginfomessageoccurserror:{},newRuntimeException());longendSystem。currentTimeMillis();longtimeendstart;System。out。println(time);}}}
  与1。1节相比,一个很明显的变化就是error日志的执行平均耗时到了4050ms,要比1。1节中的info日志慢不少,这是为什么呢?原因就在于调用logger。error(String,Throwable)时为了打印堆栈加载了每个调用节点的class,代码在:ch。qos。logback。classic。spi。PackagingDataCalculatorcomputeBySTEPprivateClassPackagingDatacomputeBySTEP(StackTraceElementProxystep,ClassLoaderlastExactClassLoader){StringclassNamestep。ste。getClassName();ClassPackagingDatacpdcache。get(className);if(cpd!null){returncpd;}注意这行代码ClasstypebestEffortLoadClass(lastExactClassLoader,className);StringversiongetImplementationVersion(type);StringcodeLocationgetCodeLocation(type);cpdnewClassPackagingData(codeLocation,version,false);cache。put(className,cpd);returncpd;}
  在bestEffortLoadClass中则会尝试类加载:privateClassbestEffortLoadClass(ClassLoaderlastGuaranteedClassLoader,StringclassName){ClassresultloadClass(lastGuaranteedClassLoader,className);if(result!null){returnresult;}ClassLoadertcclThread。currentThread()。getContextClassLoader();if(tccl!lastGuaranteedClassLoader){resultloadClass(tccl,className);}if(result!null){returnresult;}try{returnClass。forName(className);}catch(ClassNotFoundExceptione1){returnnull;}catch(NoClassDefFoundErrore1){returnnull;}catch(Exceptione){e。printStackTrace();thisisunexpectedreturnnull;}}ch。qos。logback。classic。spi。PackagingDataCalculatorloadClassprivateClassloadClass(ClassLoadercl,StringclassName){if(clnull){returnnull;}try{returncl。loadClass(className);}catch(ClassNotFoundExceptione1){returnnull;}catch(NoClassDefFoundErrore1){returnnull;}catch(Exceptione){e。printStackTrace();thisisunexpectedreturnnull;}}
  java。lang。ClassLoaderloadClass(java。lang。String)这个方法就是我们熟知的加载类的接口,其实会在className维度加锁。到这里为什么logger。error比logger。info慢多大家应该就猜到了,logger。error会打印出异常的堆栈,在高并发的场景下如果某个接口频繁抛异常,那在打印error日志的时候要各个线程要先去加载异常堆栈上各个类信息,产生锁竞争,然后才会在appender维度排队。一个常见的现实场景是下游服务限流或者直接宕机了,容易因为logback引发系统的毛刺。二、异步日志配置不当造成线程泄露
  其实在高并发的场景下,一般都会将日志配置为异步打印,其原理大概如下图所示:
  AsyncAppender将LoggingEvent扔到一个队列里,然后会有一个单独的线程从队列中消费LoggingEvent,并派发到具体要干活的Appender中,因为避免了直接直接调用writeBytes,所以性能应该有非常大的提升。我们对logback的配置稍作改动,采取异步的方式打印日志:fileUsersidealismDesktoplog。txtfileencoderpatternlogger{35}msgnpatternencoderappenderappenderrootlevelDEBUGrootconfiguration
  并采样了每次打印日志的耗时如下图所示:
  令人震惊的一幕出现了,在并发量比较大的场景下,异步打印日志的的性能与同步相比竟然差了10倍!这是为什么呢?上文说到,logback异步日志的实现原理是一个生产者消费者模型,问题在于在大流量的场景下,分配线程这个单线程的消费能力是赶不上生产能力的,最后导致所有的线程在日志打印的阻塞队列上排队。此时通过arthas也可以看到线程的排队情况,如果这是线上的业务系统,业务线程早被日志的阻塞队列吃光了,会引起业务响应异常〔arthas9341〕threadThreadsTotal:780,NEW:0,RUNNABLE:13,BLOCKED:745,WAITING:4,TIMEDWAITING:3,TERMINATED:0,Internalthreads:15IDNAMEGROUPPRIORISTATECPUDELTATIMEINTERDAEMON10AsyncAppenderWorkemain5RUNNAB43。010。0900:13。7falsetrue77arthascommandexecsystem5RUNNAB4。90。0100:0。02falsetrue39testlogthreadmain5BLOCKE0。750。0010:0。14falsefalse71testlogthreadmain5BLOCKE0。710。0010:0。15falsefalse37testlogthreadmain5BLOCKE0。710。0010:0。14falsefalse74testlogthreadmain5BLOCKE0。690。0010:0。15falsefalse67testlogthreadmain5BLOCKE0。690。0010:0。14falsefalse1C2CompilerThread210。680。0010:1。68falsetrue69testlogthreadmain5BLOCKE0。660。0010:0。15falsefalse55testlogthreadmain5BLOCKE0。660。0010:0。14falsefalse38testlogthreadmain5BLOCKE0。650。0010:0。15falsefalse36testlogthreadmain5BLOCKE0。650。0010:0。14falsefalse28testlogthreadmain5BLOCKE0。650。0010:0。15falsefalse50testlogthreadmain5BLOCKE0。650。0010:0。14falsefalse36testlogthreadmain5BLOCKE0。640。0010:0。14falsefalse三、其他问题
  除了上面提到的几个在高并发大流量场景下特有的坑外,还有一些其他的坑这里列一下,因为网上的博客比较多了,这里不再赘述https:www。elietio。xyzpostsf6b1711c。html《低版本bug导致totalSizeCap参数不生效》logback版本过低导致SizeAndTimeBasedRollingPolicy不生效的问题四、最佳实践
  应当遵循以下几个原则:
  【最佳实践一】日志工具对象的logger应当声明为privatestaticfinal声明为private是为了安全性考虑,防止logger被其他类非法使用声明为static和final则是因为在类的声明周期内无需变更logger,并且占用内存也更小
  【最佳实践二】日志字符串通过拼接即占用了额外的内存,也不直观,应当使用占位符
  【最佳实践三】日志内容和日志级别相符合debug和trace一般是开发者调试程序使用,线上应关闭这类日志info日志应当记录重要且无风险的信息,如上下文初始化,定时任务开始执行或者远程连接建立等场合warn日志应当记录可能有风险,但是不会影响系统继续运行的错误,如系统参数配置错误,用户请求参数不正确等。或者是在一些耗时异常的场景,如一次请求超时,一次sql执行超过2秒等error日志用于程序出错打印堆栈,不应该输出程序问题之外的其他信息
  【最佳实践四】高并发系统应少打或不打info日志,且应当配置为异步日志,当阻塞队列满时采取丢日志的策略,以保证业务系统正常运行

3点思考!清华女神颜宁选择深圳,给福州这座城市什么启示?科学家颜宁宣布离开美国,将协助深圳创建医学科学院的话题,最近密集刷屏。大家纷纷关注这枚清华女神的陈年往事的同时,也有人探讨颜宁为何选择深圳?在很多人看来,颜宁和深圳有点双向奔赴的意OPPO不讲武德,骁龙7拍照旗舰下跌840元,前后双旗舰人像镜头现在有很多人买手机都只关注性能,但是手机买来后却几乎不怎么玩游戏,过了一两年之后手机被淘汰掉,可能也都没有完全释放出CPU的潜能,这些朋友基本都遵循一个误区,那就是同价位买性能强的衣服起球先别扔!用它,吸剃一体,高效去球,旧衣变新衣秋冬季衣服的购物链接下面,经常会看到的问题起球吗?不管便宜的还是贵的,其实很多衣服,诸如针织衫羊毛衫毛衣卫衣光腿神器打底裤和毛呢大衣等等,穿的次数多了都不可避免地会起球。起了毛球的快船官宣伦纳德伤情!76人有好消息,篮网做出决定,威少言简意赅本赛季NBA常规赛已经进行了八分之一,比赛打到这个地步,其实已经能说明一些问题,毕竟比赛样本数量足以支撑一些观点。NBA就是这样,你往往看好的球队,他们却刷新认知。不看好的球队,却看了64岁肖雄的穿搭,我发现穿衣不扮嫩,从容老去才真美年龄越大越感叹岁月不饶人,在人间忽已至秋的时刻,也有人在为岁月已暮而感慨。与其整天因为年龄期期艾艾,不如来看看64岁的肖雄老师,以从容的姿态让人看到大龄女性的美!看了肖雄从容不迫的十年,人的一辈子有几个十年一眨眼便是一天,一回眸却也十年凌晨四点,突然醒来,但不感意外!多年来,在每年的某一个阶段,总会生物钟失调,早上早早醒来,起初倍感煎熬,最后坦然接受,或起床清茶两杯,或外出走走跑跑,我要成菜我要成菜!隔离日久,呆呆卧在柜角的几头白皮蒜也憋出了芽。平日里,蒜不稀奇,也不相离。生吃入菜,皆与佳肴随行,成就着丰富多彩的味道。但往往是,这饺子真好吃这菜真香,蒜很寂寞,它想成菜站在秋天的末尾,看枫叶层林尽染在这个陪着枫叶飘零的晚秋,才知道你不是我一生的所有再听一首晚秋,悠悠旋律飘过今年的晚秋时节。在玉龙县的世界记忆遗产公园里,看那枫叶层林尽染,晚秋的氛围更加浓厚,有枫叶飘零,也有悠悠部分苹果iPhone用户反映升级iOS16后FaceID出现问题IT之家11月6日消息,部分数量的iPhone用户近期报告说,在更新到iOS16后,FaceID无法立即工作,出现了问题。目前还不清楚有多少人受到FaceID错误的影响,也不清楚是下月发布?OPPOFindN2折叠屏截图曝光,刘作虎都不敢泄密为了取得高端机差异化发展,近两年安卓厂商都杀入折叠屏赛道,希望可以在高端领域分得一杯羹。最新消息显示,OPPOFindN2将于下个月发布,距离上一代产品过去正好一年时间,搭载骁龙8下巴比三星S22Ultra还窄?realme真我10系列官宣11月17日发布随着手机行业内卷化程度日益加剧,手机的硬件配置也迎来了显著的提升,诸如大功率快充大电池高刷屏以及高像素镜头等配置,随着成本不断地下探,如今已然逐步落地到中端机型身上,让消费者得以用
国庆假期首日,韶关这些景点最火!全市消费市场销售额超2000万10月1日国庆假期首日,韶关迎来八方游客。初步统计,10月1日我市接待游客29。46万人次。哪个景区最受欢迎?一起来看看!全市40个A级景区,实际开放38个,共接待游客36251人保时捷上市,超豪华汽车能打赢电动化翻身仗吗?汽车电动化真正让中国车企成为顶尖猎手。在大众集团的推动下,保时捷汽车集团独立上市,顺利登陆德国法兰克福证券交易所,股票代码为P911,市值达到750亿欧元,超越奔驰宝马,成为全球市奇瑞新能源终于做到了,QQ冰淇淋导购指南中年人对沉稳风格的车型往往比较钟意,大气的外观设计和精致的内饰是这类车型的特色,无论是上班还是接送孩子都是极佳的选择。今天给车友们带来的是QQ冰淇淋(参数询价图片)。让我们来一起了力压华为Mate50Pro夺冠,小米12SUltra成安卓口碑之王对于高端产品来讲,各品牌相对于销量更在意的是口碑。记得某位手机大佬讲过这个档次的机型代表着各品牌的技术代表着各品牌对于高端产品的理解。因为这个档次的产品参数与体验已经不是最重要的东十月换手机,优先考虑这几款,性价比高用着放心价格还不贵转眼进入十月,各大品牌的手机发布得都差不多了,如果想要在十月换新手机的话,可以先看看这三款,性能优越外观抗打,最关键的是价格良心,做到了真正的性价比神机。第一款华为mate50pr我们都无法改变世界,及时行乐才是真谛不要总想着我要功成名就,我要名垂千古,我要被世人所记住,甚至还有人妄想要长生不老。对于我们大多数普通人来说,我们都无法改变世界,我们只是宇宙中的一小粒尘埃而已,就像那亚马逊平原中几曝奥运女双亚军患罕见重病,不能再打羽毛球了藤井瑞希2012年伦敦奥运羽毛球女双银牌得主藤井瑞希,近期自曝患上罕见疾病再生障碍性贫血,今后可能将彻底退出羽坛,再也打不了羽毛球了。藤井瑞希垣岩令佳是日本女双十余年前的主力选手,如果不买华为Mate50,还有哪些国产旗舰值得选?尽管mate50系列确实给我们带来一定的惊喜,但是它依旧是4G手机,是一个非常致命的缺陷。当然,如果你比较喜欢华为手机且不介意4G手机,还是可以考虑一下的。并且后续mate50系列MotoG724G手机一加NordWatch手表发布微信公布朋友圈十大谣言电动狗摩托罗拉MotoG72手机已经在印度推出,作为MotoG71的继任者而出现。与前者不同的是,MotoG72只提供4G网络服务,没有5G连接。MotoG72手机采用居中打孔屏,拆个手机给你看!iPhone14真的和13一样吗?6。1英寸的苹果14定价5999元起售,虽然和13相比起售价未变,但其实配置和功能上有一些升级。处理器上,苹果14依然搭载的A15芯片,不过是5核满血版GPU。后摄虽然还是双摄,但双十一换手机,有3类手机不适宜捡漏,来听听内行人的分析一转眼已经过去元旦到了年底了,这个时候应该有很多朋友都有换手机的打算,很多厂家也为了在年底把手机清理库存会进行一些打折机器,或者降价。使得很多年底想要换手机的朋友认为这是一个捡漏的
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网