首页 > 编程知识 正文

java压力测试(全链路设计师的薪资)

时间:2023-05-04 09:24:46 阅读:63729 作者:3161

背景热情的天空系统流量大幅增加,例如“双十一”这样的流量,在面临性能问题时可能会手足无措。 为了解决这个问题,您需要知道当流量增长到数倍时,系统中的哪些组件或服务会成为整个系统的瓶颈。 在这种情况下,可能需要进行全链路压力测试。

以我过去的网络项目经验,流量翻了好几次。 例如增加10倍,进行了多次全链路压力测试,确实经历了一些漏洞,本文主要介绍设计全链路压力测试平台的经验。 我希望对你有帮助。

首先,什么是压力测试? 怎么测量全链路的压力?

压力测试的压力测试(简称)是什么,我想在业界的共享中听说过很多次。 当然,你可能在项目研发过程中做过压力测试。 所以,对你来说压力测试并不陌生。

但是我想提醒你,自己是怎么做压力测试的? 像很多同学一样,先搭建一套与正式环境功能相同的测试环境,并且导入或者生成一批测试数据,然后在另一台服务器,启动多个线程并发地调用需要压测的接口(接口的参数一般也会设置成相同的,比如,想要压测获取商品信息的接口,那么压测时会使用同一个商品 ID)。最后,通过统计访问日志或者查看测试环境的监控系统,来记录最终压测 QPS 是多少之后,直接交差?

这么做压力测试其实是不正确的

首先,在做压力测试的时候,最好使用在线数据和在线环境。 因为,无法判断自己构建的测试环境和正式环境的差异是否会影响压力测试的结果。 其次,压力测试使用在线流量,而不是模拟请求。 通过复制流量,可以将在线流量复制到压力测试环境中。 模拟流量的访问模型和在线流量有很大的不同,因此对压力测试的结果有很大的影响。 例如,当你获取商品信息时,在线流量获取不同商品的数据。 这些商品的数据有些命中了缓存,有些未命中缓存。 使用同一商品ID进行压力测试时,不会只将第一个请求命中缓存,而是在请求后将数据库中的数据放回缓存中,然后的请求一定会命中缓存。 这种压力测试的数据没有参考价值。 请勿从一台服务器启动通信。 这样很容易成为此服务器的性能瓶颈,不会提高压力测试的QPS,最终会影响压力测试的结果。 另外,为了尽可能真实地模拟用户请求,倾向于将产生业务的机器配置在CDN节点等离用户近的位置。 没有这个条件,可以放在不同的机房,尽量保证压力测试结果的真实性。 很多学生之所以有这个问题,主要是因为他们不完全理解压力测试的概念,认为只要是使用多个线程同时请求服务的接口,就可以对接口进行压力测试。

那么究竟什么是压力测试呢?

压力测试是指在高同时大流量下进行的测试,测试人员通过观察系统在峰值负载下的性能,可以发现系统中存在的性能隐患。

压力测试是发现常见系统存在问题的方式,也是保障系统可用性和稳定性的重要手段。 在压力测试过程中,不能只通过一个核心模块进行压力测试。 压力测试目标必须包括访问层、所有后端服务、数据库、缓存、消息队列、中间件和依赖的第三方服务系统及其资源。 因为随着用户访问行为的增加,包括上述组件服务在内的整个链路都会受到不确定的大流量影响。 因此,它们需要依赖压力测试来发现可能存在的性能瓶颈。 这针对整个调用链路执行的压力测试也称为“全链路压测”

在internet项目中,功能迭代速度快,系统复杂性也越来越高,因此新添加的功能和代码很可能成为新性能瓶颈。 半年前做压力测试的时候,一台机器可能一秒钟能承担1000次要求,现在很可能一秒钟承担800次要求。 因此,压力测试作为保障系统稳定性的常规手段,应该周期性地进行。

但是,要进行全链路压力测试,通常需要联合多个团队(如DBA、运维、依赖服务端和中间件体系结构)进行协作,这既增加了人工成本,也增加了沟通协调成本。 另外,在压力测试过程中,如果没有很好的监控机制,也会对在线系统产生不良影响。为了解决这些问题,我们需要搭建一套自动化的全链路压测平台来降低成本和风险

如何建立全连杆压力测量平台建立全连杆压力测量平台,主要有两个关键。

一是流量隔离。 压力测试是在正式环境下进行的,需要区分压力测试的流量和正式流量,可以对压力测试的流量进行单独的处理。

一个是风险的控制。 这意味着尽量避免压力测试对普通访问用户的影响。 因此,总链路压力测量平台通常需要以下模块:

流量结构与生成模块压力测量数据隔离模块系统健康度检测和压力测量流量干扰模块整体压力测量平台结构图如下:

为了更清楚地了解每个模块是如何实现的,我们将更详细地介绍压力测量平台的每个模块,以便于您设计适合自己业务的全链路压力测量平台。 首先,让我们来看看压力测试的流量是如何发生的。

压力测量数据的生成一般来说,我们系统的入口流量是来自客户的HTTP请求。 所以,我们在系统高峰时期把这些

入口流量拷贝一份,在经过一些流量清洗的工作之后(比如过滤一些无效的请求),将数据存储在像是 HBase、MongoDB 这些 NoSQL 存储组件或者云存储服务中,我们称之为流量数据工厂。

这样,当我们要压测的时候,就可以从这个工厂中获取数据,将数据切分多份后下发到多个压测节点上了。在这里,我想强调几个,你需要特殊注意的点:

首先,我们可以使用多种方式来实现流量的拷贝。最简单的一种方式:直接拷贝负载均衡服务器的访问日志,数据就以文本的方式写入到流量数据工厂中。但是这样产生的数据在发起压测时,需要自己写解析的脚本来解析访问日志,会增加压测时候的成本,不太建议使用。另一种方式:通过一些开源的工具来实现流量的拷贝。这里,我推荐一款轻型的流量拷贝工具GoReplay(或tcpcopy),它可以劫持本机某一个端口的流量,将它们记录在文件中,传送到流量数据工厂中。在压测时,你也可以使用这个工具进行加速的流量回放,这样就可以实现对正式环境的压力测试了。其次,如上文中提到,我们在下发压测流量时,需要保证下发流量的节点与用户更加接近,起码不能和服务部署节点在同一个机房中,这样可以尽量保证压测数据的真实性。

另外,我们还需要对压测流量染色,也就是增加压测标记。在实际项目中,我会在 HTTP 的请求头中增加一个标记项,比如说叫做 is stress test,在流量拷贝之后,批量在请求中增加这个标记项,再写入到数据流量工厂中。

数据如何隔离

将压测流量拷贝下来的同时,我们也需要考虑对系统做改造,以实现压测流量和正式流量的隔离,这样一来就会尽量避免压测对线上系统的影响。一般来说,我们需要做两方面的事情。

一方面,针对读取数据的请求(一般称之为下行流量),我们会针对某些不能压测的服务或者组件,做 Mock 或者特殊的处理,举个例子。

在业务开发中,我们一般会依据请求记录用户的行为,比如,用户请求了某个商品的页面,我们会记录这个商品多了一次浏览的行为,这些行为数据会写入一份单独的大数据日志中,再传输给数据分析部门,形成业务报表给到产品或者老板做业务的分析决策。

在压测的时候,肯定会增加这些行为数据,比如原本一天商品页面的浏览行为是一亿次,而压测之后变成了十亿次,这样就会对业务报表产生影响,影响后续的产品方向的决策。因此,我们对于这些压测产生的用户行为做特殊处理,不再记录到大数据日志中。

再比如,我们系统会依赖一些推荐服务,推荐一些你可能感兴趣的商品,但是这些数据的展示有一个特点就是展示过的商品就不再会被推荐出来。如果你的压测流量经过这些推荐服务,大量的商品就会被压测流量请求到,线上的用户就不会再看到这些商品了,也就会影响推荐的效果。

所以,我们需要 Mock 这些推荐服务,让不带有压测标记的请求经过推荐服务,而让带有压测标记的请求经过 Mock 服务。搭建 Mock 服务,你需要注意一点:这些 Mock 服务最好部署在真实服务所在的机房,这样可以尽量模拟真实的服务部署结构,提高压测结果的真实性。

另一方面,针对写入数据的请求(一般称之为上行流量),我们会把压测流量产生的数据写入到影子库,也就是和线上数据存储完全隔离的一份存储系统中。

针对不同的存储类型,我们会使用不同的影子库的搭建方式。

如果数据存储在 MySQL 中,我们可以在同一个 MySQL 实例,不同的 Schema 中创建一套和线上相同的库表结构,并且把线上的数据也导入进来。而如果数据是放在 Redis 中,我们对压测流量产生的数据,增加一个统一的前缀,存储在同一份存储中。还有一些数据会存储在 Elasticsearch 中,针对这部分数据,我们可以放在另外一个单独的索引表中。

通过对下行流量的特殊处理以及对上行流量增加影子库的方式,我们就可以实现压测流量的隔离了。

压力测试如何实施

在拷贝了线上流量和完成了对线上系统的改造之后,我们就可以进行压力测试的实施了。在此之前,一般会设立一个压力测试的目标,比如说,整体系统的 QPS 需要达到每秒 20 万。

不过,在压测时,不会一下子把请求量增加到每秒 20 万次,而是按照一定的步长(比如每次压测增加一万 QPS),逐渐地增加流量。在增加一次流量之后,让系统稳定运行一段时间,观察系统在性能上的表现。如果发现依赖的服务或者组件出现了瓶颈,可以先减少压测流量,比如,回退到上一次压测的 QPS,保证服务的稳定,再针对此服务或者组件进行扩容,然后再继续增加流量压测。

为了能够减少压力测试过程中人力投入成本,可以开发一个流量监控的组件,在这个组件中,预先设定一些性能阈值。比如,容器的 CPU 使用率的阈值可以设定为 60%~70%;系统的平均响应时间的上限可以设定为 1 秒;系统慢请求的比例设置为 1% 等等。

当系统性能达到这个阈值之后,流量监控组件可以及时发现,并且通知压测流量下发组件减少压测流量,并且发送报警给到开发和运维的同学,开发和运维同学就迅速地排查性能瓶颈,在解决问题或者扩容之后再继续执行压测。

业界关于全链路压测平台的探索有很多,一些大厂比如阿里、京东、美团和微博都有了适合自身业务的全链路压测平台。在我看来,这些压测平台万变不离其宗,都无非是经过流量拷贝、流量染色隔离、打压、监控熔断等步骤,与本文中介绍的核心思想都是相通的。因此,你在考虑自研适合自己项目的全链路压测平台时,也可以遵循这个成熟的套路。

最后总结

我带你了解了做压力测试常见的误区,以及自动化的全链路压测平台的搭建过程,这里你需要了解的重点是:

压力测试是一种发现系统性能隐患的重要手段,所以应该尽量使用正式的环境和数据;对压测的流量需要增加标记,这样就可以通过 Mock 第三方依赖服务和影子库的方式来实现压测数据和正式数据的隔离;压测时,应该实时地对系统性能指标做监控和告警,及时地对出现瓶颈的资源或者服务扩容,避免对正式环境产生影响。

这套全链路的压力测试系统对于我们来说有三方面的价值:

其一,它可以帮助我们发现系统中可能出现的性能瓶颈,方便我们提前准备预案来应对;其次,它也可以为我们做容量评估,提供数据上的支撑;最后,我们也可以在压测的时候做预案演练,因为压测一般会安排在流量的低峰期进行,这样我们可以降级一些服务来验证预案效果,并且可以尽量减少对线上用户的影响。

所以,随着你的系统流量的快速增长,你也需要及时考虑搭建这么一套全链路压测平台,来保证你的系统的稳定性。

 

推荐资料 微服务架构实战 - 我的经验分享总结2017~2020(系统架构师)架构演进过程-从信息流架构到电商中台架构【总结】当我们聊高并发时,到底是在聊什么?如何真正地掌握高并发设计能力?我的专栏 SpringBoot系列专栏SpringCloud系列专栏高可用高并发实战专栏微服务架构实战DevOps实战专栏程序化广告实战专栏架构思维成长系列教程

 

 

至此,全部介绍就结束了

 

 

-------------------------------

-------------------------------

 

我的CSDN主页

关于我(个人域名,更多我的信息)

我的开源项目集Github

 

期望和大家一起学习,一起成长,共勉,O(∩_∩)O谢谢

欢迎交流问题,可加个人QQ 469580884,

或者,加我的群号 751925591,一起探讨交流问题

不讲虚的,只做实干家

Talk is cheap,show me the code

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。