`

从0到1构建美团压测工具

阅读更多

美团内部的RPC服务大多构建在Thrift之上,在日常开发服务的过程中,需要针对这些服务进行压力测试(以下简称压测)来发现潜在问题。常用的方法有:

  • 使用一些脚本语言如:Python、Ruby等,读取线上日志构建请求,用多线程模拟用户请求进行压测
  • 使用开源工具进行压测

然而,无论采取哪种方法,压测都是一个十分耗时而又繁琐的过程,主要痛点有:

  • 需要写很多代码解析日志,还原请求,对于比较复杂的请求,解析很容易出错
  • 需要搭建脚本或者工具的运行环境,通常这一过程比较耗时
  • 由于打压方法没有统一,导致打压的结果指标比较混乱,有的结果甚至以终端输出的方式展示,非常不直观
  • 对一个应用的打压测试,由于环境、代码的问题,导致组内同学很难共享

针对上述问题,提供一个简单好用的压测工具是十分有必要的。

是否有必要重复造轮子

在构建压测工具之前,对于一些现有的开源工具进行了调研。现在主流的压测工具主要有以下几个:

JMeter

JMeter是一个比较老牌的压测工具,主要针对HTTP服务进行打压,该工具在以下方面并不满足美团内部的压测需求:

  • 默认不支持Thrift的打压测试
  • 需要本地安装,并且配置复杂
  • 对于用户操作并不友好

Jmeter

twitter/iago

iago 是一个由Twitter开源的压测工具,支持对HTTP、Thrift等服务进行压测,其主要问题如下:

  • 对每个压测应用都需要创建一个项目
  • 压测结果并不直观
  • 流量重放依赖本地文件
  • 项目依赖于一个较老版本的Scala,搭建不便
  • 相关文档比较少

除此之外,当时还考察了 Gatling、 Grinder、 Locust 等一些常见的压测工具,都因为适用场景和美团的需求有些出入而排除了。

综上,针对当前压测工具的一些现状,构建一个简单易用的压测工具还是很有必要的。

目标

针对之前提到的痛点,新的压测工具主要提供以下功能:

  • 线上流量拷贝
  • 简单易用的操作界面(接入压测的时间应该控制在1小时以内)
  • 清晰的图表能反映压测应用的各项指标
  • 满足包括Thrift、HTTP等服务的压测需求

如何构建

抽象

目标已经明确,怎么实现呢?首先是抽象压测的过程。 
一个典型的压测过程如图所示,首先在init方法里面,进行一些初始化的工作,比如连接数据库,创建客户端等。接下来,在run方法里面发出压测请求,为了保证能够对服务产生足够的压力,这里通常采用多线程并发访问,同时记录每次请求的发起时间和结束时间,这两个时间的简单相减就能够得到每次请求的响应时间,利用该结果就可以计算出TP90、平均响应时间、最大响应时间等指标,等压测结束后,通过destroy方法进行资源回收等工作。

Model

以上过程可以用接口表示,无论是压测Thrift服务还是HTTP服务,本质上都是这三个方法实现的不同。考虑到压测工具的灵活性和通用性,压测工具可以将这个接口交给打压测试的同学实现,而压测工具则重点实现多线程打压,打压结果的聚合等比较耗时的工作。

  interface Runner {
    def init(Test app) // 初始化压测
    def run(Test app, String log) // 每次打压请求,传入log方便构建请求
    def destroy(Test app) // 压测完毕后,回收资源
}

拷贝流量

Thrift服务打压的难点之一就是如何简单地拷贝线上真实流量用来构建打压请求。一些大型的Thrift服务数据结构非常复杂,写打压脚本的时候需要很多代码来解析日志,而且容易出错。 因此提供一个简单好用的拷贝流量方法是十分有必要的。

在这里压测工具提供了一个叫VCR(录像机)的工具来拷贝流量。VCR能够将线上的请求序列化后写到Redis里面。

考虑到用户需要查看具体请求和易用性等需求,最终选取了JSON格式作为序列化和反序列化的协议。同时需要部署在生产环境,为了降低对线上服务的影响,这里采取了单线程异步写的方式来拷贝流量。

VCR

聚合数据

应用打压完成后,需要一些指标来评估压测结果,常见的指标有:

  • 最大响应时间
  • 平均响应时间
  • QPS
  • TP90
  • TP50

压测工具采用了 InfluxDB 来完成数据的聚合工作。 
以TP90为例子,仅需要一行查询就能实现需求。

  SELECT PERCENTILE(response_time, 90) FROM test_series GROUP BY time(10s)

架构

整体而言,整个打压过程如下:

Loading Test

实践

拷贝流量

美团内部的服务大多使用Java来构建,VCR以Maven Package的方式提供给用户。

对用户来说只需要2行代码可以拷贝流量。

为了不影响线上服务,通常选取单台机器进行流量拷贝工作。

  
public class TestAppRPC implements TestApp.Iface {

    private Vcr _vcr = new Vcr("testapp"); // 指定拷贝流量的key

    @Override
    public TestResponse echo(TestRequest req) throws TException {
        _vcr.copy(req); // 拷贝操作
        long start = System.currentTimeMillis();
        TestResponse response = new TestResponse();
        return response;
    }
}

一旦流量拷贝完成后,通过Web界面,用户能够查看日志的收集情况和单条日志的详情。 
vcr

压测逻辑实现

压测工具采用Groovy来进行编写。对每个应用来说,只需要实现 runner接口就可以实现对应用的打压。

  interface Runner {
    def init(Test app)
    def run(Test app, String log)
    def destroy(Test app)
}

以Thrift服务为例:

  
class TestServiceRunner implements Runner {

    RPCService.Client _client
    TTransport _transport;

    @Override
    def init(Test app) {
        def conf = app.config // 读取应用配置
        _transport = new TFramedTransport(new TSocket(conf.get("thrift_service_host") as String, conf.get("thrift_service_port") as int))
        TProtocol protocol = new TBinaryProtocol(_transport)
        _client = new RPCService.Client(protocol)
        _transport.open()
    }

    @Override
    def run(Test app, String log) {
        TestRequest req = Vcr.deSerialize(log, TestRequest.class) // 将拷贝流量反序列化
        _client.echo(req) // 发送请求
    }

    @Override
    def destroy(Test app) {
        _transport.close() // 关闭服务
    }
}

创建应用

实现以上接口后,就可以对应用进行打压了。

用户可以通过Web界面创建应用,除了必填配置以外,用户可以按照应用灵活配置。

vcr

性能指标

用户可以通过直观的图表来查看应用的各种性能指标。

result

结束语

压测工具上线以来,已经接入了20多个应用,完成数百次打压实验,现在应用的接入时间仅需要15~30分钟。保证了美团服务的稳定和节省了开发同学的时间,使大家告别了以往繁琐冗长的打压测试。

 

 

http://tech.meituan.com/

分享到:
评论

相关推荐

    linux串口压测工具

    "Linux串口压测工具"是一个专门用于测试串口性能的软件,通过模拟大量数据传输来评估串口的稳定性和处理能力。下面将详细介绍该工具的相关知识点。 首先,我们要理解什么是串口压测。串口压力测试是针对串行通信...

    TCP协议压测工具源代码

    5. **延迟与响应时间**:TCP压测工具会测量数据包从发送到接收的时间,以及应用层的响应时间,这些指标对于实时性要求高的应用非常重要。 6. **并发连接数**:压测工具能模拟大量并发连接,测试服务器在处理多连接...

    TCP压测工具

    服务类型 工具是针对基础的应用层服务进行测试,支持测试应用协议用TCP和UDP。 测试用户数 是工具向服务创建的连接数...工具提供了几种格式以便于使用都构建具体的协议消息,支持的格式分别是:ascII,utf8,hex和base64.

    es 压测工具 esrally-dist-1.4.1.tar.gz

    **Elasticsearch (ES) 压力测试工具——Rally 深度解析** Elasticsearch(简称ES)作为一款流行的开源搜索引擎和数据分析引擎,其性能和稳定性至关重要。为了确保ES在高负载下的表现,开发者和运维人员需要进行压力...

    web服务器压测工具

    在IT行业中,Web服务器压测工具是至关重要的,它们用于模拟大量用户同时访问网站或应用,以测试其在高负载下的性能、稳定性和响应速度。本文将深入探讨这个主题,并结合"店铺detail页面性能测试报告.xlsx"这个文件,...

    高仿美团(和美团基本一模一样)

    通过这个项目,开发者可以学习到如何构建一个类似美团这样的大型在线服务平台,涵盖团购、外卖、酒店预订等多个业务模块。 【描述】:“一位大神高仿的,很详细的,可以学到很多培训学不到的知识。” 这个高仿美团...

    服务压测工具jmeter

    JMeter是Apache组织开发的一款强大的性能测试工具,主要用于对Web应用程序进行压力测试和服务质量评估。它的全称为Apache JMeter,版本为5.4.1,是目前广泛应用的开源测试工具之一,尤其在IT行业中,对于确保系统在...

    仿美团菜单页面

    1. **前端框架**:通常会选择React、Vue或Angular等现代前端框架来构建这样的页面,因为它们提供了组件化开发、状态管理以及性能优化等功能。 2. **数据渲染**:页面中的商品分类和列表需要动态加载,可以使用虚拟...

    2018年美团点评技术年货(中)

    可能会介绍Hadoop、Spark等工具在美团的实践,以及如何通过数据挖掘和机器学习提升用户体验和运营效率。 2. **分布式系统**:面对高并发和实时性的需求,美团的技术团队可能分享了他们在分布式计算、微服务架构、...

    一个.NET 6开发的轻量级Web应用程序压测工具

    LoadTestToolbox的源码可以帮助开发者深入理解压力测试的实现细节,学习如何利用.NET 6框架构建类似工具。源码中可能包括以下几个关键部分: 1. **请求生成器**:用于构造HTTP请求并发送到目标Web服务器。 2. **负载...

    Android studio仿美团app

    【Android Studio 仿美团App开发详解】 在移动应用开发领域,Android Studio是Google推出的一款强大的集成开发环境(IDE),广泛用于构建Android应用程序。本项目旨在通过Android Studio来模仿美团App的功能,包括...

    美团外卖源码

    1. **Web框架**:美团外卖源码可能会使用诸如Spring Boot、Django、Flask等流行的Web开发框架,这些框架提供了快速构建复杂应用的基础。 2. **数据库设计**:源码中会包含对数据库的使用,如MySQL、MongoDB等,涉及...

    仿美团商品列表展示购物车

    在IT行业中,构建一个类似美团的商品列表展示及购物车功能是一项常见的需求,它涉及到前端界面设计、数据管理以及用户交互等多个方面。以下是对这个主题的详细解析: 首先,"商品列表展示"是电商网站的核心部分,它...

    美团免登接口

    1. **接口使用指南**:文档会详细说明如何集成美团的免登接口,包括请求和响应的格式、请求的URL、必要的参数设置等。开发者需要按照指南配置自己的应用程序,以调用接口并处理返回的结果。 2. **参数加密机制**:...

    仿美团小程序源码,电商小程序源码

    【仿美团小程序源码】是针对电商领域设计的一款开源代码,旨在为开发者提供学习和二次开发的平台。这款源码的出现,使得开发者能够快速理解并掌握小程序的开发流程,同时也能根据自身需求进行定制化改造,以创建具有...

    美团点评_W3690.HK再看美团:本地生活羽翼渐丰,生态构建迈征程.rar

    《美团点评_W3690.HK再看美团:本地生活羽翼渐丰,生态构建迈征程》 这篇报告深入探讨了美团点评的发展历程、业务布局以及未来战略方向,尤其聚焦于美团在本地生活服务领域的成就和生态系统的构建。美团点评,作为...

    仿美团外卖-微信小程序源码.zip

    2. **源码导入文档教程.docx** - 另一个Word文档,专门指导用户如何将源码导入到开发环境中,可能涵盖了微信开发者工具的使用、项目的初始化设置、以及如何运行和调试代码等内容。 3. **源码导入视频教程.mp4** - ...

Global site tag (gtag.js) - Google Analytics