热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

3步排查,3步优化,探针性能损耗直降44%

应用接探针除了安全问题,最担心的就是占用系统性能影响业务正常运转,今天分享一个实际案例告诉大家如何来降低探针的性能损耗。下表为某用户的2条核心链路在200并发压测下的性能数据对比,

应用接探针除了安全问题,最担心的就是占用系统性能影响业务正常运转,今天分享一个实际案例告诉大家如何来降低探针的性能损耗。

下表为某用户的2条核心链路在200并发压测下的性能数据对比,可以看见在接入探针后性能损耗居高不下。

在这里插入图片描述


3步快速排查

1.对比链路差异

首先想到的排查方案是通过skywalking监控进行排查,对比应用在接入探针和未接入探针的情况下,性能表现的差异在哪,具体的的性能消耗在哪个中间件。

在对比skywalking监控的链路耗时,确实可以观察到未接入探针比接入探针和链路的RT高,但是不清楚是否存在客户环境问题或者skywallking上的链路有断裂的问题,信息并不全面无法准确定位。

在这里插入图片描述

在这里插入图片描述


2.插件排除法

在无其它有效信息时,尝试通过排除法定位具体影响性能的插件。具体做法是先整理链路用到的中间件,先移除所有中间件插件,再逐一增加单个中间件插件,不断的进行压测,观察哪个插件对性能的影响比较大。依靠这个方法定位成功到dubbo与logback两个插件,它们对性能影响比较大。

在这里插入图片描述


3.性能数据收集

在压测测试的同时,我们在agent框架内增加了对中间件插件interceptor方法执行的耗时统计代码,这部分数据会统一输出到固定的日志文件中。此外我们开发了与之配套的性能日志分析程序,配合日志收集脚本,可以对整个链路的所有应用打印的性能数据进行分析,输出汇总出一份中间件interceptor的统计结果,这份结果可以直观的看到每个中间件的性能耗时占比。

统计结果样例:

在这里插入图片描述

性能收集代码展示:

在这里插入图片描述


3步具体优化

1.减少切点

agent产生性能损耗的终归原因是因为agent增强中间件代码后,会修改目标类的字节码,植入一些额外的逻辑,正是这些额外的逻辑带来了额外的耗时。切点越多植入的逻辑越多,整个链路的损耗就可能越高,所以尽可能的减少切点的数量一定会减少性能损耗。

按照这个思路,我们将前面排查出来耗时占比较高的logback中间件进行了重新设计。原先logback的实现有三个切点,分别负责:影子appender的注册、流量标识、日志隔离,经过重新设计后,优化为一个切点实现所有功能。


2.静默&业务流量过滤

尽管中间件插件的增强逻辑不尽相同,但agent在植入到目标类的字节码都是统一的。他们都有统一入口,前置的运行逻辑都是同一套框架,实际运行时序图如下:

在这里插入图片描述

实际上有很多Interceptor的增强逻辑只有压测流量时才会执行,可这部分interceptor的执行全部需要经过前面从Messager到AdviceListener的一系列调用,这是完全没有必要并且会带来一定的性能损耗。这种无用调用可以在最前端做个判断,从开始就过滤掉,在达到效果的同时降低性能损耗。

在这里插入图片描述

为此我们对框架进行了改造,让类似这种interceptor能在最前端就把流量过滤掉,避免执行无意义的逻辑。同时在最前端增加了静默开关,静默开关可以一键禁用掉所有中间件增强逻辑的执行,一定程度上可以代替卸载操作。相比卸载来说它不会还原实际的字节码,也不会回收内存占用,但是会更加轻量级,响应更快,影响更小。

改造后的运行时序图:

在这里插入图片描述


3.中断逻辑优化

对logback插件进行重新设计后产生了一定效果,但是从性能采集的数据来看,性能损耗占比最高的还是logback插件。经过反复斟酌发现logback本身已经没有在进一步优化的空间了,于是将目光转向了框架层面,最后将重点放在了优化CutoffInterceptor类型中断机制。

CutoffInterceptor是一个类似挡板的Interceptor,它可以中断源码本身的运行,并且支持对返回值替换。比如数据库隔离的实现,我们一般会实现一个CutoffInterceptor,在压测流量经过时返回影子数据库的connection代替业务connection,以实现数据的隔离。logback同样也是实现了一个CutoffInterceptor,在压测流量经过时返回影子的appender替换业务的appender实现日志隔离。

CutoffInterceptor内部的实现原理是通过异常机制实现的,在替换返回值时,实际上是抛出了一个异常由上层捕获,实现对源代码的中断。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

众所周知,在java中通过抛出实现流程控制的效率其实是比较低的,我们内部测试验证也证实了这点,一个空逻辑的CutoffInterceptor和同样的一个空逻辑Interceptor的性能差距相差几十近百倍。恰好logback这种日志类型的中间件执行频率是非常高的,所以导致这块的性能损耗一直下不去。于是我们把CutoffInterceptor的中断机制进行了优化,抛出异常改为了先advice设置中断标记,再由上层判断去控制中断。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


最终结果

经过一系列的优化动作之后,两条核心链路的性能损耗都有了大幅度的提升,链路A性能损耗由48%下降至4%,链路B的性能损耗由35%下降至3.4%。

在这里插入图片描述



推荐阅读
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • Linux系统中Java程序Too Many Open Files问题的深入解析与解决方案
    本文详细分析了在Linux环境下运行的Java应用程序中可能出现的“Too many open files”异常现象,探讨其成因及解决方法。该问题通常出现在高并发文件访问或大量网络连接场景下,对系统性能和稳定性有较大影响。 ... [详细]
  • 面神经F波技术及其在面瘫诊疗中的应用进展
    本文总结了李健东博士及其团队对面神经F波技术的研究成果,探讨其在面瘫诊断和预后评估中的应用。该技术自1996年建立以来,经过大量临床验证,已被广泛应用于早期面瘫的诊断,并显示出优于其他方法的准确性。研究还揭示了F波与面瘫预后的密切关系,为提高治愈率提供了重要依据。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • NTP服务器配置详解:原理与工作模式
    本文深入探讨了网络时间协议(NTP)的工作原理及其多种工作模式,旨在帮助读者全面理解NTP的配置参数和应用场景。NTP是基于RFC 1305的时间同步标准,广泛应用于分布式系统中,确保设备间时钟的一致性。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • Java多线程实现:从1到100分段求和并汇总结果
    本文介绍如何使用Java编写一个程序,通过10个线程分别计算不同区间的和,并最终汇总所有线程的结果。每个线程负责计算一段连续的整数之和,最后将所有线程的结果相加。 ... [详细]
author-avatar
骑猪猪-逛恋空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有