编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由杨硕在高可用架构群分享。点击上方蓝字订阅高可用架构可获取进群机会。
“目前美团压测项目接入的服务 40 ,打压的次数 1000 ,很好的完成了线上业务的打压需求。” 杨硕
为什么要搞一个通用的压测工具美团内部的 RPC 服务大多构建在 Thrift 之上,在日常开发服务的过程中,需要针对这些服务进行压力测试(以下简称压测)来发现潜在问题。常用的方法有:
然而,无论采取哪种方法,压测都是一个十分耗时而又繁琐的过程,主要痛点有:
通常要让一个同学压测某一服务,很多时候需要耗费 2~3 天时间,并且很多同学的表情都是这样的: 为了解决这个问题提供一个简单好用的压测工具是十分有必要的。 有没有必要自己造轮子呢?如果有现成的解决方案,那再好不过了。 常见的压测工具JMeter JMeter 是一个比较老牌的压测工具,主要针对 HTTP 服务进行打压,该工具在以下方面并不满足美团内部的压测需求:
Twitter/iago Twitter/iago是一个由 Twitter 开源的压测工具,支持对 HTTP、Thrift 等服务进行压测,其主要问题如下:
除此之外,当时还考察了 Gatling、Grinder、Locust 等一些常见的压测工具,都因为适用场景和美团的需求有些出入而排除了。综上,针对当前压测工具的一些现状,构建一个简单易用的压测工具还是很有必要的。 构建自己的压测工具针对之前提到的痛点,新的压测工具主要提供以下功能:
其实很多复杂问题在实用性和灵活性权衡过后,都能用一个简单模型表示,压测问题也一样,我们将压测过程抽象,可以用这个图表示: 首先,在 init 方法里面,进行一些初始化的工作,比如连接数据库,创建客户端等。 其次,在 run 方法里面发出压测请求,为了保证能够对服务产生足够的压力,这里通常采用多线程并发访问,同时记录每次请求的发起时间和结束时间,这两个时间的简单相减就能够得到每次请求的响应时间,利用该结果就可以计算出 TP90、平均响应时间、最大响应时间等指标。 最后,等压测结束后,通过 destroy 方法进行资源回收等工作,比如关闭 RPC服务的连接,关闭数据库等。 如果用接口可以这样表示: 无论是 HTTP 还是 Thrift 服务的压测,本质都是 run 方法的不同。 有了基本模型后,我们要解决的另外一个痛点是,如何简单地拷贝线上真实流量用来构建打压请求,一些大型的 Thrift 服务数据结构非常复杂,写打压脚本的时候需要很多代码来解析日志,而且容易出错。 为了避免这种情况,我们提供了一个叫 VCR(录像机)的工具来拷贝流量。VCR 能够将线上的请求序列化后写到 Redis 里面。考虑到用户需要查看具体请求和易用性等需求,最终选取了 JSON 格式作为序列化和反序列化的协议。同时需要部署在生产环境的一台机器上,为了降低对线上服务的影响,这里采取了单线程异步写的方式来拷贝流量,如下图: 解决了流量拷贝问题后,我们接下来需要按照我们采集的指标进行数据聚合运算。常见的指标有:最大响应时间,平均响应时间,QPS,TP90,TP50,这些指标可以评估服务的性能。 这里我们采用了 InfluxDB 来完成数据的聚合工作,所有聚合指标都是一行 SQL 搞定,非常快速。以 TP90 为例子,仅需要一行查询就能实现需求。 SELECT PERCENTILE(response_time, 90) FROM test_series GROUP BY time(10s) 综上,压测工具的流程图如下: 这是第一期的实现,大概花了 1 周左右的业余时间,等项目上线后,应用的压测接入时间得到了明显的缩短。下图是每个步骤的平均耗时: 细心的同学可能已经发现了,VCR 是用虚线表示的,原因是对于新上线的服务,不需要拷贝流量,只需要在实现 runner 的过程中,通过代码构造请求数据即可。项目刚上线时,大家还不熟悉,第一次应用接入需要耗时 20 到 40min,等大家有经验后,下个应用的接入时间会缩短到 15min 左右。对于服务的 owner 来说,该压测工具更为灵活,他可以在 runner 接口中自由实现压测逻辑。如果二次打压的话或者修改参数的话,只需要在网页上点击鼠标即可完成。下图是其中某个服务的压测结果: 项目上线后,陆陆续续有各事业部的同学开始使用,大家普遍反应操作简单,但是也存在以下几个问题:
我们开始针对上述问题进行了解决,针对第一个问题,我们采用 Akka 来做一个分布式的扩展,将应用的角色分为 master、worker、counter。 Master 负责进行任务分发,worker 进行打压,然后将打压的的结果发给 counter 进行汇总写入 InfluxDB。 第二个问题,我们在简单模型的基础上进行更高级别的封装,用户上传 Thrift 文件后,我们将 Thrift 文件编译成为模板代码后,自动生成对应的接口。同时我们也有相应的 HTTP 服务适配模块。 针对最后一个问题,我们在压测机器上部署了 agent,压测期间机器的数据能够通过 agent 源源不断的提交上来,这样用户能够清晰的看到被打压服务所在机器的性能指标。 这是架构升级图,大家可以结合我刚刚说的三点看看: 整个项目的技术栈是 Ratpack InfluxDB ActiveJDBC AngularJS,主力开发语言是 Groovy。 最后说下项目的发展情况,项目接入的服务 40 ,打压的次数 1000 ,很好的完成了同学们的打压需求。在做压测工具的时候最大的感触是:很多复杂的问题都能用很简单的模型来解释,在简单模型的基础上按照用户的需求不断开发适配才能成为一个好的框架,Storm,Hadoop 都是如此。项目有些细节的部分大家可以参考我们美团的技术 Bloghttp://t.cn/R4KWHrA。 Q |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|