导读:做性能分析听到最多的歪理就是,服务做水平、垂直扩容、分表分库、读写分离、XX中间件、资源静态化等等但是归根到底这些方案都是为了尽可能减少对数据库的访问以及堆栈的释放,提高数据库IO的读写速度和程序的运行效率。
系统都是逐渐演进的,一个系统在运行中必须是根据场景逐渐地提高优化性能。高并发就是对资源的节约的考验,这种考验除了更换优秀和先进的技术,优化架构,还在于从小处出发,对尽可能节约的资源进行节约。
而在一个系统的数据访问中,系统的瓶颈往往是来自于数据库,因此我们要尽可能减少对数据库的访问!
一、背景
最近一段时间粉丝可能留意到,技术号一直没有更新多少技术文章。因为近期都在做一直在做性能优化。
在业务模块在并发量起来以后,接口的性能瓶颈就愈发变得明显。
最近一段时间粉丝可能留意到,技术号一直没有更新多少技术文章。因为近期都在做一直在做性能优化。
在业务模块在并发量起来以后,接口的性能瓶颈就愈发变得明显。
配置解析和函数路由服务接口性能堆栈分析
本篇主要针对配置布局资源文件过大,导致接口耗时过长问题分析解决。
二、日志链路追踪
排查性能如果从代码层面出发少不了堆栈分析,但是目前大部分服务都为了便于服务扩容、升级都做了微服务处理,日志分析排查免不了通过链路 ID 追踪日志《微服务分布式架构中,如何实现日志链路跟踪?》
▐ 链路追踪日志改造 - RPC 接口
通过 restTemplate、Openfeign 的形式访问其他服务的接口时,就会携带起始位置生成的 traceId、spanId 到下一个服务单元。但是没有详细实现,这里做下简单补充便于后面理解与使用。
阅读 Spring-Web 源码,对于远程接口的调用拦截可以实 ClientHttpRequestInterceptor
拦截客户端 HTTP 请求。这个接口的实现可以注册到 RestTemplate ,以修改传出的 ClientHttpRequest 和/或传入的 ClientHttpResponse 。拦截器的主要入口点是 intercept(HttpRequest, byte[], ClientHttpRequestExecution) 。
计算 RPC 接口耗时与日志记录,这样在做接口分析的时候可以针对性能较差、耗时高的接口有针对性性排查分析。
远程服务的接口性能暂时不做分析,目前很明确耗时:1528ms 应该存在很大的性能问题。
▐ 链路追踪日志改造- 传播线程变量
但是目前只统计出远程接口耗时是远远不够的,我们需要知道接口总耗时以及对堆栈分析才能精准定位到问题。
记录 HTTP 监控信息
这里需要补充下不是所有的接口我们都需要捕捉和统计分析,我们可以统一接口规范。如页面请求统一以/data/
开头,RPC 接口统一以/api/
开头这样可以分别区分两则的统计信息,避免记录错乱。
▐ 链路追踪日志改造- 统计 RPC 调用次数
上面👆🏻的两处的处理目前也只能精确度到当前 HTTP 请求有哪些 PRC 接口请求?每个 PRC 接口请求耗时多少?作为核心服务不太会去关系业务服务的接口细节,如果需要针对 PRC 接口的主服务做进步性能分析即可。
因此还需要进步统计出所有 RPC 接口的总耗时和次总次数。
通过“线程变量”传递 RPC 接口的请求的次数。记得先前有类似出路过服务之间的认证问题也是通过请求头传递。《Spring Cloud中如何保证各个微服务之间调用的安全性?》
累计完请求数量继续传递下去,以此类推来统计 RPC 接口的请求总数
这里做了简单阈值限制,背景不难想到:如果一个接口频繁调用另外一个服务超过 20、30 次此时,我们就应该考虑服务之间数据同步或者映射问题。
所以在计算 RPC 接口的请求总次数加了阈值限制,若 RPC 调用次数超出范围则输出警告日志
▐ 链路追踪日志改造 - 链路日志统计展示
至于链路追踪日志的展示,自己使用就不用太关注图形化样式问题,这里建议直接使用 Thymeleaf 模板引擎进行渲染展示,也就有了文章开头的图片
三、总结
对于问题分析我们首先能遇到的总是一个较大的问题,在算法中我们常会用分治算法。一言以蔽之:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破。
回顾整个处理思路
-
微服务日志埋点处理,记录链路日志并统计
-
监听 HTTP 请求后,记录微服务服务之间 RPC 接口耗时
-
监听 HTTP 请求后,记录 RPC 接口深度(请求次数)
-
记录 RPC 请求总总耗时与总占比
至此算是完成了我们做链路日志分析的第一步:统计分析 HTTP 请求所触发的外部服务的性能消耗。
关注我的微信公众号【清朝程序猿】除了技术我还会聊点日常,有些话只能悄悄说~