导语 | Tars 是由腾讯主导开源,并募捐给 Linux 基金会的微服务 RPC 框架。而 TarsBenchmark 的推出是对 Tars 生态的进一步欠缺,它反对的在线压测性能极大升高开发测试人员在线评测服务性能应用门槛。本文是对腾讯专家工程师陈林峰在云 + 社区沙龙 online 的分享整顿,心愿与大家一起交换。
点击此链接查看残缺直播回放
一、TarsBenchmark 是什么
1. 常见测压工具
咱们在服务后盾的一些 APP 上线之前,通常会做一些性能的评估,而后会评测一下。例如开发的我的项目大略能够服务多少用户,以及可能承当多大的并发量?
(1)Apache Bench
经典的性能评测工具 AB,也叫 Apche Beach,它是一个 http 协定服务的压测工具,也是泛滥 WebAPP 的经典压测工具,采纳 C 语言开发,不便易用也具备较好的性能。
然而它也有有余的中央,次要在于它采纳的是单线程模式,而咱们当初后盾的服务器很多都是多核,因而它不能施展咱们服务器的全副性能。
(2)Wrk
新的压测工具 Wrk,它补救了 AB 单线程设计的有余。它采纳的网络是事件驱动的形式,在网络 IO 方面有比拟好的体现。
另外它反对脚本语言。能够在 lua 生成一些随机内容。当初大部分后盾的服务都是采纳分布式的部署,如果仅对某一个申请一直的重放,容易导致单机高负载,而不能反馈实在集群的服务能力。而 wrk 在这两方面进行了改良,因而它的利用十分地宽泛。
(3)GHZ
在微服务里还有一个很典型的压测工具 GHZ,他是 GRPC 框架下的一个压测工具,开发语言是 golong,因而具备很好的并发能力。
它的用例采纳 JSON 的格局组织,它利用 PB 良好的反射个性很容易将 JSON 的用例转换成网络传输所须要的二进制形式,因而应用起来也十分不便。
(4)JMeter
最初给大家介绍一下 JMeter 工具,它是采纳 Java 语言开发,提供了图形界面交互模式,反对分布式部署,能够补救单机性能的有余。
然而因为 JMeter 相当于采纳线程的模型,用一个线程模仿一个用户申请,实际上当线程积攒到肯定的数量之后,线程调度和竞争会带来一些额定的 CPU 开销,所以它的单机性能存在一些有余。
2. TarsBenchmark 是什么?
常见的压测工具可能还有很多,这里就不一一开展,下文次要介绍 TarsBenchmark,看看这款压测工具到底有哪些个性?
(1)单机运行的压测工具
TarsBenchmark 是基于 Tars 生态的一个压测工具,它次要服务 Tars Service,而 Tars 是腾讯开源的多语言、高性能、易运维的微服务框架,它的通信协定采纳 Tars,而 Tars 是相似于 PB 二进制的一种传输的协定,并且它是由腾讯齐全自主研发的。目前参加的开发人数曾经快靠近 300 人了,在 Github 上你输出 TarsCloud 就能够进入官网介绍文章理解咱们的 Tars。
Tars 反对 C ++ 等多种开发语言,Tars 绝对其余开发框架比方 PRPC 等,还提供一个服务平台,并且能够帮忙开发者和企业疾速构建稳固牢靠的散布式微服务利用,开发人员只须要关注业务逻辑,从而进步研发和经营效率。
(2)一个反对云端压测平台
TarsBenchmark 不仅能够在单机上运行,它还提供一个云端的压测 Web 平台,即能够反对分布式压测,让开发者能够很不便从容进行 TarsService 压测,来评估 Tars 服务的性能。
(3)不仅仅 ForTarsService
当你的团队外面应用非 Tars 协定服务,它也能够很容易满足。在前面的 TarsBenchmark 应用中,我会为大家介绍怎么去开发非 Tars 协定,用咱们的工具很容易满足第三方协定的压测。
3. 解决了哪些问题?
那么 TarsBenchmark 到底解决了哪些问题呢?次要在于以下三点:
- 高性能:充分发挥多核 CPU 计算能力,8 核机器可输入 40Wtps 能力;
- 高扩展性:反对任意一个 Tars 接口压测,敌对反对非 Tars 协定;
- 简略易用:用例采纳 JSON 格局,编写便当,反对线上云压测。
二、TarsBenchmark 原理
1. 工具压测原理
(1)多过程
首先来介绍高性能设计的实现,咱们在上文也剖析了 AB 和 Wrk,其中 Wrk 对 AB 的降级次要在于采纳多线程实现,而 TarsBenchmark 也是采纳多过程的形式。
在主过程上咱们会依据服务器的物理核数去 fork 相等数量的压测过程,各压测过程之间是齐全隔离的,也就是独立去运行,防止了过程与过程之间相互抢夺临界资源。当然这个压测过程数是能够通过参数指定的,默认会依据 CPU 的无效核数去 Fork 对应的一个过程。
(2)网络解决
在网络方面采纳的是事件驱动的形式,就是通过定时发包器发包,基于网络事件收发,无效防止网络 IO 的阻塞。
另外在连贯方面咱们采纳连接池,在连接池对每个连贯采纳连贯复用的形式。在咱们剖析 AB 压测原理的时候发现:当 AB 链接建设起来并发完一个报文进来的时候,收到这个报文之后才会发动下一个报文,因而在这个链接中它会有期待操作,不能齐全的把链接利用起来和匀速产生 QPS。
而 TarsBenchmark 是基于连贯复用形式,不依赖于对端是否返回。对于内部服务返回这个场景,当咱们在用 AB 压测的时候,有时候会发现服务器的返回十分及时,那么这个时候 AB 就能够达到很高的一个输入能力;然而当服务端返回耗时较高的时候,AB 输入能力就会呈现乘数级的降落。
例如: CGI 在 20ms 的返回和 200ms 的返回,雷同链接数会影响 AB 十倍的性能输入差别,因而咱们感觉链接设计形式是一种节约。
在 TarsBenchmark 设计的时候思考到这一点,它基于协定包的序号能够做到不依赖服务端回包机会去抉择下一个报文发送工夫,通过返回包序号去定位到发包的工夫,从而计算压测过程当中的状态信息。
(3)多维监控
咱们的压测过程和主过程之间有一些通信,是通过无锁队列来实现信息交互,包含上文提到的耗时的统计、错误码的统计都是通过无锁队列来实现的。
(4)协定扩大
另外在协定这一块,咱们采纳的是协定代理工厂这种模式,TarsBenchmark 默认提供的是 Tars 协定的压测。然而如果你有一些公有协定,能够参考 Tars 协定的实现,也能够集成进来,代理工厂能够自动识别新减少的协定。
(5)反对随即数据
在 Tars 协定压测中,TarsBenchmark 能够反对随机数据的生成,另外也提供随机函数,它能够无效防止压测过程中对惟一的申请进行重放。
(6)主动生成用例
在 Tars 协定这一块,咱们还提供一个工具,用以主动生成 Tars 服务所需的测试用例。TarsBenchmark 的测试用例采纳的是 JSON 格局,用户只须要编辑 Value 能够很轻松得发动压测。
2. 分布式压测原理
分布式压测次要是解决同时多人应用平台的问题。它的次要部件由四个局部组成。
第一局部是 WebUI 入口,它集成在 Tarsweb 下面,提供了一套非常简单的交互。
第二局部是 CGI,次要做测试用例的治理,其中包含数据库的 CRUD 操作、权限的管制。
第三、四局部是后盾服务,蕴含一个压测 Admin 服务和 Node 服务 (压测 node)。Node 服务负责执行具体的压测工作,应用工具压测完结之后随零碎主动销毁,而在分布式压测的时候,是依赖压测 admin 来进行销毁的。
为升高复杂度,TarsBenchmark 在设计的时候采纳的是多线程形式(linux 系统调度 CPU 资源是以线程为单位)。压测 admin 会承受 CGI 的指令,比方用户在输出的 QPS 调度所需的压测 node 时,因为压测 node 调度最小单元是线程,一个线程能够设置 3~5 万的输入能力,而后依据这种单线程能力咱们再计算须要的线程数,最初把它调配到咱们的压测 node 外面去执行压测。
TarsBenchmark 会把这些数据会暂存在压测 Admin 外面,压测 Admin 服务个别举荐主备部署的模式,分布式压测用例编写也是采纳 JSON 格局,后盾有个工具对每个接口帮忙用户主动生成 demo 用例。用例的编写也十分的简略。TarsBenchmark 也会提供测试性能,不便用户压测的时候去验证以后性能是否失常。
3. 协定转换
咱们晓得 Tars 是一种二进制、可扩大的跨语言的协定,它反对 C ++、PHP、Java 和 Node,其本质是 TLV 的协定。然而整个压测,如果采纳 JSON 这种组织,如何转成二进制?这可能是整个压测最大的一个难点,那么 TarsBenchmark 是怎么去解决这个问题的呢?
首先咱们剖析一下 Tars 的协定编解码原理,T 蕴含 Tag 和 Type,传输的时候二进制后面有四个 bit,体现为一个 Tag。接下来是示意数据的 Type,Tars 协定最多能够反对 16 种数据类型,目前曾经编到 14 种。这是 Tars 最开始的时候就这样设计的,目前咱们数据的类型并没有超出咱们的编码,阐明过后的这种设计还是具备肯定的前瞻性。
这其中有七种根本类型,还有三类简单类型。举个例子,以很常见的两个构造体嵌套为例,它编出来的二进制后果如上图所示,最左边是最终编码进去的一个成果,首先咱们看到这个是 B 构造体二进制编码的成果,从第一个 0 开始,代表了它就是这个 a 变量的一个 Tag,咱们查找 a,发现它是构造体的起始,进入到 a 构造体之后第一位也是 0,tag 对应的是 int 数据,而后是两个字节的数据,4 进 2 的话对应 1、2、3 和 4。
16 咱们能够看到 1 是它的 bits1,对应 s 的变量,6 是代表它的实俊,它的字节长度是 4,咱们能够看到是跟的 616、63 和 64,对应就是 abcd,而后 0p 完结代表这个构造体曾经完结了。接下来就是 14,咱们发现 1 是代表这种 float 数据类型,而后 4 对应的是四个 bits 的数据,反序列化当前对应这样的一个构造体,跟咱们两头这个构造体对应起来。
如果采纳编辑二进制去压测咱们的 Tars,我想大部分人都会解体,一个简略的构造体可能还能够写进去,然而当你构造体的成员很多或者超过了十个,或者构造体外面又嵌套构造体,预计大部分开发都会抓狂,因而利用这种形式编辑显然是不可取的。
那么 TarsBenchmark 是怎么做的呢?咱们会依据 Tars 的接口文件,利用 IDL 工具,首先将这种语法数生成一个形容文件,形容文件蕴含三个局部:Tag、Type 和 Name。对于 Web 平台会存到 DB 外面去,采纳 RPC 调用的 Tars 在 body 之外还有一层 head,它有四个要害信息: 一个申请 id, 服务名称,函数名称,以及参数二进制 body。
在实现的 TarsBenchmark 会去查这个形容文件的 Name,而后通过 Name 取得 Tag 和 Type,再从用例外面取得 Value,再通过 Tars 的编解码规定写入二进制 Buffer 外面,最终实现了 JSON to Tars 的这种转换。
它的逆向转换其实情理是相通的,咱们首先把它从二进制还原成 Tars 的 Tag 和 Type,而后咱们通过 Tag 在形容文件中查到 Type 和 Name,而后通过 Name 和 Value 还原 JSON 的格局,以上是一个 RPC 调用过程在客户端的协定转换流程。
4. 第三方 Service 压测
如果采纳第三方协定其实也很简略,实现四个函数接口就能够实现对于非 Tars 协定的反对。
这四个函数接口别离是是初始化接口,断包接口(采纳 TCP 长链接的流式格局,响应包到哪截止,在这个 input 函数外面去实现就能够),编码接口,解码接口。
申请编码接口的实现,这外面有一个很重要的参数 id,咱们零碎每次申请会生成一个 id,如果这个接口反对就能够把 id 返回回来。
以咱们的 Tars 为例,咱们在 head 外面有一个 id 填充进去,RPC 响应回来的时候会携带同样的 id,TarsBenchmark 会依据这个申请应答,计算这个申请的耗时和成功率。如果第三方服务不反对返回序号,须要在 isSupportSeq() 返回 false,它就进入无序模式,无奈做到链接复用。
以上就是 TarsBenchmark 的设计原理。
三、TarsBenchmark 的应用
1. 代码目录构造
源码门路: https://github.com/TarsCloud/TarsBenchmark。
首先看一下 TarsBenchmark 的代码构造,次要分为四个局部,从下往上看最开始的是工具,服务,公共模块和资源文件。重点介绍一下公共模块,次要是 3 局部:协定,网络和监控。
- 协定反对: 默认会反对两种协定,一种是 HTTP 协定,一种是 Tars 的协定。
- 监控: 压测独特的数据都是通过监控器暂存,无锁队列通信也在此实现。
- 网络: 采纳事件驱动形式,非阻塞 Socket 模式设计。
2. 代码编译
代码编译次要是两个局部,一个是 TarsCpp,如果有云端压测的需要,TarsWeb 也是依赖项。
编译的步骤也很简略,首先将代码克隆下来,新建一个长期目录通过 cmake 实现编译,就能够生成三个程序,别离是 tb、nodeserver 和 adminserver。很多时候最小的需要只须要一个工具 tb,工具能够间接在单机执行,而当你有云端压测需要,执行一下 install 装置脚本,一键装置到 Tarsweb 中去。
这里次要有几个参数,一个是 web 的 host,adminserver 举荐和 Tars 根底服务部署在一起,因为它自身不会耗费太多的 CPU,然而 nodeserver 不同,举荐独自部署,并且它是能够程度扩大的。
3. 单机工具压测
对于单机工具的压测应用,有如下参数能够依据理论状况调整:
- - c 是压测的链接数,- s 是最大的 qbs 的限度,如果没有指定 - s 就会尝试探测服务端最大性能去实现压测;
- -D、- P 压测指标服务器的端口,指标服务器能够执行多个地址,通过逗号进行区隔;
- - n 参数: 指定压测的过程数。- T 指定 TCP 或者 UDP,默认 TCP;
- - p 参数: 接口通信协定,如果是本人的公有协定,能够改成公有协定的名字。
每次压测的周期外面,都会有一些耗时的散布、成功率的统计、均匀耗时的 P99 或者 P90 的这种统计信息,能够周期性的打印进去,避免出现压测过程当中不理解以后服务的状况,还有就是继续的这种压测工夫也是能够通过 - i 参数去指定的。
4. 云端分布式压测
云端压测应用非常简略,在 TarsWeb 接口调试里有一个压测入口,用例能够看进去,你新增的时候会主动生成这些用例,当你压测的时候,你只须要指定这些压测指标 IP,QPS 就能够随时随地发动压测,并能够看到压测过程中的服务体现。
四、TarsBenchmark 成绩
1. 倒退历程
咱们是在 2016 年的时候在腾讯外部开源,最开始它只是一个工具,反对的协定也很少,次要是 Tars,而 Tars 在外部是叫做 taf 协定。
在 2018 年之后反对协定数变得十分丰盛,之前很古老的服务都能够通过这个工具反对到,目前在外部应用还是非常宽泛的。另外它反对云端 Web 压测,每周大略应用的人数也超过了数百人,不须要登录到 IDC 机器上,随时随地都能够发动。
往年 4 月份咱们也把它奉献给开源社区 TarsCloud,造福社区的小伙伴,欢送大家多多提出指教。
2. 同类型比照
目前应用的反应十分不错,绝对于其余的一些开源工具,这个工具是采纳 c ++ 语言开发的,有两种模式,一种是多过程,也就是工具采纳多过程的模式,在云端压测是采纳线程池的模式,反对分布式的压测,单机性能绝对 AB 和 Wrk 也有一个很好的体现。
最重要的是 TarsBenchmark 反对匀速的发包,因为它基于连贯复用的形式,在间断发送上不依赖申请返回,因而能够做到匀速的发包,也反对随机内容的生成。另外它还反对线上的压测,这也是 TarsBenchmark 的一个很重要的亮点。
以上就是明天的分享内容,欢送各位小伙伴们前来参加生态奉献。另外如果对咱们的岗位有需要,能够间接发简历到我的邮箱外面来:linfengchen@tencent.com。
五、Q&A
Q:wrk 和 TarsBenchmark 之间的区别是什么?如何做压测选型?
A: 这个问题很好,方才咱们说 wrk 相对来说跟咱们的 TarsBenchmark 的网络模型其实是一样的,它是基于多线程以及网络附用的模式。然而 wrk 是纯 http 的协定压测工具,http 协定能够了解为无序的模式,无奈做到链接复用,性能还有一些制约,也没法做到匀速发送。
另外一方面,wrk 次要是一个纯 HTTP 协定,它并不能反对到公有的协定,公有的协定用起来还是有一些吃力,咱们的 TarsBenchmark 在协定扩展性方面会体现的会更好一点。
Q:咱们当初 TarsBenchmark 代码量是多少?
A: 咱们还是很轻量的,咱们统计无效代码是几千行左右。
我印象当中如同 3000 到 4000 行之间,是代码量非常少的工程,学习曲线也是十分平缓的,不会太简单,只有有一些 C ++ 语言根底就能够很快的上手。
Q:TarsBenchmark 以及 TarsJMeter 的区别?
A: 方才暖场的时候也说,咱们的 JMeter 是采纳线程的模式去模仿用户,在一个线程外面执行一个用户的申请响应,这种线程的调度开销还是十分大的,你试想一下在一个机器上起一万个线程的规模,线程之间因为线程调度依赖操作系统,因而像 JMeter 的网络模型的性能不会很好。
当然也有一些人对这种 JMeter 做了一个扩大,因为 JMeter 最大的利用是具备很好的扩展性,它反对分布式压测,单机不行,能够分布式补救,这是 JMeter 比拟大的长处。
另外它的上报都是插件的设计思维,还是蛮先进的,比如说咱们一些后果的数据,咱们能够上报到其余的一些 UI 语言下面做一些出现,这一块是 JMeter 很大的一个劣势,咱们在做市面上常见的几款压测工具调研的时候,把它们架构的短处交融在一起就最终造成咱们的 TarsBenchmark。
总结下来,TarsBenchmark 有更好的单机性能体现。
Q:是为什么不必 golong 语言开发
A: 这个有一些背景,咱们最开始是在 2015 到 2016 年做的这款产品,Tars 那个时候的生态,在咱们外部次要是以 C ++ 为主,golong 在网络这一块其实做了很多底层的能力反对,咱们内源版本也有 golong 的实现,然而目前没有开源进去。
通过比照发现 C ++ 的性能会比 golong 的网络模型好一点点,次要是体现在编解码这一块效率会更高一点。
Q:Tars 反对哪些接口,http 反对吗?
A: 这个是反对的,你用最新版的 Tars 开发框架是能够写本人的接口,所以咱们的 TarsBenchmark 自身的话也是反对 http 协定的压测。
Q:是不是反对这种 kafka 做一些压测?
A:kafka 这些组件基本上都有本人的一些压测工具,其实我集体倡议,你用它框架组件的一些压测工具就能够满足了,当然你本人有趣味去钻研一下咱们的 TarsBenchmark,按我方才说的思路实现三个函数、四个函数,也能够去实现对你 kafka 提取的一个压测。
Q:为什么效率会这么高?还能够进步吗?
A: 方才在工具外面我也跟大家介绍了一下,次要是四个方面,一个就是多过程,充分发挥 CPU 的计算效率。第二方面是咱们采纳这种非组装的网络模型,第三是基于这种网络链接附用的形式防止链接在那里闲置,第四是所谓的这种通信都是采纳非阻塞的。
还有没有方法持续进步?咱们当初也发现了,比如说咱们在简单的 Tars 接口的编解码效率这块还是会有一些问题,所以如果说还有什么进步的话,次要就是在编解码这块要思考零拷贝的思维,咱们的操作系统和压缩工具之间尽量零拷贝去缓冲区的操作,包含这种二进制的协定以 Tars 为例,咱们把它转换成 Tars 尽量采纳更高效的编解码的效率工具,目前咱们在尝试做进一步的晋升。
Q:TarsBenchmark 目前在腾讯云下面看到相干的产品和解决方案,将来会不会上腾讯云?
A: 目前,次要是以开源的这种模式去共建,以开源的形式提供,目前没有上云的打算,如果采纳 Tars 的生态,咱们能够收费提供给宽广的用户去应用,包含企业和集体。
Q:采纳的是 C++ 11 规范设计的吗?
A: 这个是对的,咱们是采纳 C++ 11 的规范去实现的。另外我也受 Tarscloud 官网委托,如果大家对 Tars 的比拟关注,能够关注它的官网,它的源码就是在刚刚的 PPT 外面,大家能够关注云 + 社区的公众号回复线上沙龙就能够获取。代码构造能够在咱们这个上一期节目,就是 Tarscloud 能力以及它的参数的一个目录,你能够本人去找相应的你感兴趣的材料去学习或尝试。
Q:大数据产品是否能够压测?
A: 你说的大数据产品指的是 idp 的压测?目前像这种大数据也有本人的一套通信协定,如果你抓住这个通信协定的法则,或者你理解它的一些协定设计的形式,其实也是能够的。