自从项目上了SkyWalking,睡觉真香!(2)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 自从项目上了SkyWalking,睡觉真香!(2)

请求量这么多,全部采集会不会影响性能?

如果对每个请求调用都采集,那毫无疑问数据量会非常大,但反过来想一下,是否真的有必要对每个请求都采集呢,其实没有必要,我们可以设置采样频率,只采样部分数据,SkyWalking 默认设置了 3 秒采样 3 次,其余请求不采样,如图示

这样的采样频率其实足够我们分析组件的性能了,按 3 秒采样 3 次这样的频率来采样数据会有啥问题呢。理想情况下,每个服务调用都在同一个时间点(如下图示)这样的话每次都在同一时间点采样确实没问题

但在生产上,每次服务调用基本不可能都在同一时间点调用,因为期间有网络调用延时等,实际调用情况很可能是下图这样

这样的话就会导致某些调用在服务 A 上被采样了,在服务 B,C 上不被采样,也就没法分析调用链的性能,那么 SkyWalking 是如何解决的呢。

它是这样解决的:如果上游有携带 Context 过来(说明上游采样了),则下游强制 采集数据。这样可以保证链路完整。

SkyWalking 的基础架构

SkyWalking 的基础如下架构,可以说几乎所有的的分布式调用都是由以下几个组件组成的

首先当然是节点数据的定时采样,采样后将数据定时上报,将其存储到 ES, MySQL 等持久化层,有了数据自然而然可根据数据做可视化分析。

SkyWalking 的性能如何

接下来大家肯定比较关心 SkyWalking 的性能,那我们来看下官方的测评数据

图中蓝色代表未使用 SkyWalking 的表现,橙色代表使用了 SkyWalking 的表现,以上是在 TPS 为 5000 的情况下测出的数据,可以看出,不论是 CPU,内存,还是响应时间,使用 SkyWalking 带来的性能损耗几乎可以忽略不计。

接下来我们再来看 SkyWalking 与另一款业界比较知名的分布式追踪工具 Zipkin, Pinpoint 的对比(在采样率为 1 秒 1 个,线程数 500,请求总数为 5000 的情况下做的对比),可以看到在关键的响应时间上, Zipkin(117ms),PinPoint(201ms)远逊色 于 SkyWalking(22ms)!

从性能损耗这个指标上看,SkyWalking 完胜!

再看下另一个指标:对代码的侵入性如何,ZipKin 是需要在应用程序中埋点的,对代码的侵入强,而 SkyWalking 采用 javaagent + 插件化这种修改字节码的方式可以做到对代码无任何侵入 ,除了性能和对代码的侵入性上 SkyWaking 表现不错外,它还有以下优势几个优势

  • 对多语言的支持,组件丰富:目前其支持 Java, .Net Core, PHP, NodeJS, Golang, LUA 语言,组件上也支持dubbo, mysql 等常见组件,大部分能满足我们的需求。
  • 扩展性:对于不满足的插件,我们按照 SkyWalking 的规则手动写一个即可,新实现的插件对代码无入侵。

我司在分布式调用链上的实践

SkyWalking 在我司的应用架构

由上文可知 SkyWalking 有很多优点,那么是不是我们用了它的全部组件了呢,其实不然,来看下其在我司的应用架构

image.png

从图中可以看出我们只采用了 SkyWalking 的 agent 来进行采样,放弃了另外的「数据上报及分析」,「数据存储」,「数据可视化」三大组件,那为啥不直接采用 SkyWalking 的整套解决方案呢,因为在接入 SkyWalking 之前我们的 Marvin 监控生态体系已经相对比较完善了,如果把其整个替换成  SkyWalking,一来没有必要,Marvin 在大多数场景下都能满足我们的需求,二来系统替换成本高,三来如果重新接入用户学习成本很高。

这也给我们一个启示:任何产品抢占先机很重要,后续产品的替换成本会很高,抢占先机,也就是抢占了用户的心智,这就像微信虽然 UI,功能上制作精良,但在国外照样干不过 Whatsapp 一样,因为先机已经没了。

从另一方面来看,对架构来说,没有最好的,最有最合适的,结合当前业务场景去平衡折中才是架构设计的本质

我司对 SkyWalking 作了哪些改造和实践

我司主要作了以下改造和实践

  1. 预发环境由于调试需要强制采样
  2. 实现更细粒度的采样?
  3. 日志中嵌入traceId
  4. 自研实现了 SkyWalking 插件

预发环境由于调试需要强制采样

从上文分析可知 Collector 是在后台定时采样的,这不挺好的吗,为啥要实现强制采样呢。还是为了排查定位问题,有时线上出现问题,我们希望在预发上能重现,希望能看到这个请求的完整调用链,所以在预发上实现强制采样很有必要。所以我们对 Skywalking 的 dubbo 插件进行了改造,实现强制采样

我们在请求的 Cookie 上带上一个类似 force_flag = true 这样的键值对来表示我们希望强制采样,在网关收到这个 Cookie 后,就会在 dubbo 的 attachment 里带上force_flag = true 这个键值对,然后 skywalking 的 dubbo 插件就可以据此来判断是否是强制采样了,如果有这个值即强制采样,如果没有这个值,则走正常的定时采样。

实现更细粒度的采样?

哈叫更细粒度的采样。先来看下 skywalking 默认的采样方式 ,即统一采样

我们知道这种方式默认是 3 秒采样前 3 次,其他请求都丢弃,这样的话有个问题,假设在这台机器上在 3 秒内有多个 dubbo,mysql,redis 调用,但在如果前三次都是 dubbo 调用的话,其他像 mysql, redis 等调用就采样不到了,所以我们对 skywalking 进行了改造,实现了分组采样,如下

就是说 3 秒内进行 3 次 redis, dubbo, mysql 等的采样,也就避免了此问题

日志中如何嵌入traceId?

输出日志中嵌入 traceId 便于我们排查问题,所以打出出 traceId 非常有必要,该怎么在日志中嵌入 traceId 呢?我们用的是 log4j,这里就要了解一下 log4j 的插件机制了,log4j 允许我们自定义插件来输出日志的格式,首先我们需要定义日志的格式,在自定义的日志格式中嵌入 %traceId, 作为占位符,如下

然后我们再实现一个 log4j 的插件,如下

首先 log4j 的插件要定义一个类,这个类要继承 LogEventPatternConverter 这个类,并且用标准 Plugin 将其自身声明为 Plugin,通过 @ConverterKeys 这个注解指定了要替换的占位符,然后在 format 方法里将其替换掉。这样在日志中就会出现我们想要的 TraceId ,如下

我司自研了哪些 skywalking 插件

SkyWalking 实现了很多插件,不过未提供 memcached 和 druid 的插件,所以我们根据其规范自研了这两者的插件

插件如何实现呢,可以看到它主要由三个部分组成

  1. 插件定义类: 指定插件的定义类,最终会根据这里的定义类打包生成 plugin
  2. Instrumentation: 指定切面,切点,要对哪个类的哪个方法进行增强
  3. Interceptor,指定步骤 2 中要在方法的前置,后置还是异常中写增强逻辑

可能大家看了还是不懂,那我们以 dubbo plugin 来简单讲解一下,我们知道在 dubbo 服务中,每个请求从 netty 接收到消息,递交给业务线程池处理开始,到真正调用到业务方法结束,中间经过了十几个 Filter 的处理

而 MonitorFilter 可以拦截所有客户端发出请求或者服务端处理请求,所以我们可以对 MonitorFilter 作增强,在其调用 invoke 方法前,将全局 traceId  注入到其 Invocation 的 attachment 中,这样就可以确保在请求到达真正的业务逻辑前就已经存在全局 traceId。

所以显然我们需要在插件中指定我们要增强的类(MonitorFilter),对其方法(invoke)做增强,要对这个方法做哪些增强呢,这就是拦截器(Inteceptor)要做的事,来看看 Dubbo 插件中的 instrumentation(DubboInstrumentation)

我们再看看下代码中描写的拦截器(Inteceptor)干了什么事,以下列出关键步骤

首先 beforeMethod 代表在执行 MonitorFilter 的 invoke 方法前会调用这里的方法,与之对应的是 afterMethod,代表在执行 invoke 方法后作增强逻辑。

其次我们从第 2,3点可以看到,不管是 consumer 还是 provider, 都对其全局 ID 作了相应处理,这样确保到达真正的业务层的时候保证有了此全局 traceid,定义好 Instrumentation 和 Interceptor 后,最后一步就是在 skywalking.def 里指定定义的类

// skywalking-plugin.def 文件
dubbo=org.apache.skywalking.apm.plugin.asf.dubbo.DubboInstrumentation

这样打包出来的插件就会对 MonitorFilter 的  invoke 方法进行增强,在 invoke 方法执行前对期 attachment 作注入全局 traceId 等操作,这一切都是静默的,对代码无侵入 的。

总结

本文由浅入深地介绍了分布式追踪系统的原理,相信大家对其作用及工作机制有了比较深的理解,特别需要注意的是,引入某项技巧,一定要结合现有的技术架构作出最合理的选择,就像 SkyWalking 有四个模块,我司只采用其 agent 采样功能一样,没有最好的技术,只有最合适的技术 ,通过此文,相信大家应该对 SkyWalking 的实现机制有了比较清晰的认识,文中只是介绍了一下 SkyWalking 的插件实现方式,不过其毕竟是工业级软件,要了解其博大精深,还要多读源码哦。



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
JSON Kubernetes Cloud Native
美女同事的烦恼:如何配置 Apache SkyWalking 告警?
技术部基本上是一个和尚庙,女生非常少,即使有女生也略微有点抽象,小婉就不一样,她气质绝佳。 上午,同事小婉刚才从老板办公室里出来,看上去一脸不悦的样子。为了表示对同事的关(ba)心(gua),我就主动和她聊一聊。
351 0
美女同事的烦恼:如何配置 Apache SkyWalking 告警?
|
编解码 前端开发
重学JavaWeb第二天(七)
重学JavaWeb第二天
93 0
重学JavaWeb第二天(七)
|
JavaScript 前端开发 Go
重学JavaWeb第三天(五)
重学JavaWeb第三天
163 0
重学JavaWeb第三天(五)
|
前端开发 Java 数据库
SpringBoot日记本系统全程直播01:先把框架搞起来撒~~
SpringBoot日记本系统全程直播01:先把框架搞起来撒~~
131 0
|
消息中间件 负载均衡 JavaScript
自从项目用了灰度发布,睡觉真香!
自从项目用了灰度发布,睡觉真香!
重学JavaWeb第二天(三)
重学JavaWeb第二天
164 0
重学JavaWeb第二天(四)
重学JavaWeb第二天
161 0
|
前端开发 容器
重学JavaWeb第二天(二)
重学JavaWeb第二天
147 0
|
前端开发 数据安全/隐私保护
重学JavaWeb第二天(六)
重学JavaWeb第二天
142 0
重学JavaWeb第二天(五)
重学JavaWeb第二天
95 0