21 如何进行高保真压测和服务扩容?

在后台架构中,压测非常常见,也是必须的工作。它能够帮我们发现微服务架构中的性能瓶颈,以及知道构建的微服务能承载的流量极限值。

但实际情况是,很多压测并不能发现瓶颈点和微服务所能承载的真实流量极限值。一方面是因为压测时使用的是人为构造的压测参数;另一方面有些时候压测场景是经过修改的,和实际的线上场景存在差异。

本讲将会聊聊如何构建一个更贴近真实场景的高保真压测,以及如何根据压测结果进行相对应的容量规划。

实施高保真压测

模拟参数进行压测是指人为构建符合被压测接口的一个或一组参数进行压测的方法,它存在以下几个问题。

首先,参数是模拟的,可能和线上真实环境有差异,进而导致压测数据失真。

假设我们要压测使用了本地缓存和Redis 来实现的查询用户基本信息接口,当使用一个或一组用户账号压测此接口时,压测出来的性能和 QPS 会非常好。因为,在压测的前几次调用之后,所有用户信息已经缓存到用户模块的本地缓存里,后续的所有压测请求都可以直接使用本地缓存的数据,因此性能会非常好。

而实际生产环境里,查询用户信息的接口请求里的用户账号并不是相同的,因此请求不会都命中本地缓存,所以它的性能要比压测时低。这就是产生失真的原因。

其次,即使抓取线上环境的一组参数进行压测,也不能完全代替真实环境,仍然存在失真的场景。

而高保真压测,从字面上就可以理解它的要求——使用和生产环境一模一样的用户请求进行压测。这样压测出的微服务的各项性能指标更加可信,因此可以作为限流和容量评估的参考标准。

那如何模拟线上请求呢?只要完成生产环境的流量录制,并把它用来压测即可。其实本讲介绍的高保真压测实现思路和“第 07 讲”基本类似,只是“第 07 讲”把录制的流量用来进行自动化测试回归。

基于生产环境的流量录制压测架构如下图 1所示:

图 1:基于流量录制的压测架构图

上述架构和“第 07 讲”的自动化回归架构类似,其中包含内置于业务进程里的流量过滤器、日志保存模块、日志下发模块、压测模块以及压测管理端。

  • 流量过滤器:和“第 07 讲”里的类似,采用 RPC 框架提供的拦截器实现,并将出入参基于 MQ 转发。

  • 日志保存模块:根据压测设置的配置,进行压测日志的收集。压测的配置包含:当次需要压测的接口和方法、收集日志的时长和数量等。需要注意的是,相比自动化回归,此处日志收集的量应该要多很多,因为通常来说,压测需要的真实用户请求数据会更多一些。因此,日志的存储也可以升级到分布式文件系统里,如 Hadoop。

  • 日志下发模块:主要功能是将压测的日志下发到压测机器里。为什么不是压测模块远程连接到分布式文件系统读取日志后,再进行压测呢?主要是因为考虑性能。压测希望在短时间内,给被压测应用一个洪峰流量。如果压测模块在发起压测请求前还需要调用其他远程接口获取数据,很大程度上,就实现不了这个洪峰流量了。因此,需要在压测前,将压测日志推送到压测机器上,压测模块可以读取本地磁盘的日志,性能将会有极大提升,可以短时间发起洪峰流量。

  • 压测模块:主要的功能是读取本地日志并调用被压测机器,并将压测信息写入存储中。

  • 压测管理端:用来设置各项压测配置以及查看压测结果值。

上述便是一个高保真压测的架构和对应模块的功能。在了解压测模块的架构后,我们再来看看压测时,被测应用需要注意的问题。

首先,最简单的被压测应用架构如下图 2 所示:

图 2:简单的被压测应用架构图

上述架构是一个非常简单的应用部署图,其中包含一个存储模块(Redis 或数据库)及一台应用机器。压测时,很大概率是应用程序所在的宿主机先达到资源的瓶颈,而不是数据存储先达到瓶颈。这可能是发生了宿主机的CPU 利用率达到 100%,或者是内存使用率满了等情况。此时,获取到的QPS 即为上述架构里单台机器能够承载的最大值。

那么,是不是拿着上述单机的最大 QPS,通过机器数量乘以单机最大 QPS,即可计算出当前线上集群能够承载的最大 QPS 呢?

答案显然是不行的,集群的QPS 并不是随着机器数量增加而线性增加的。主要原因是所有机器所处的网络是共享的、进程间的切换存在性能消耗,以及存储是共享的等因素。

在实际压测中,压测完单台机器后,可以分多次部署 2台,4 台及 8 台应用进行压测,得到对应的压测 QPS。通过不断叠加机器进行压测获得损耗比,为后续线上大规模扩容做数据准备。假如得到 1 台机器的压测 QPS 为 100,2 台的QPS为180,4 台的QPS 为 360,那么可以计为损耗比 10%。假设线上有100 台机器,由此评估线上可以支撑的 QPS为9000。

这里你可能会有疑惑,为什么不直接对线上集群进行压测,而要采用这种按比例的方式?主要有以下两个原因。

  • 线上机器并不是一成不变的。比如现在线上有100 台机器,在业务不断发展后,可能会不断扩容至 200 台或更多的机器。此时,之前直接按 100 台机器进行压测的数据就没法直接使用了。

  • 直接对线上环境进行压测会影响线上正常的业务。因为压测的应用集群和存储都是和线上共享的。如果不希望它们互相影响,那么就需要重新部署一套和线上一模一样的环境,这个资源的消耗和部署的成本会非常高。

那是不是通过上述方式压测之后,就可以根据压测值和损耗比进行压测了呢?比如,某一天运营计划做促销活动,预估带来的最大流量 QPS 为 18000/s。按上述数据,是不是扩容到 200 台机器即可了呢?

其实,并不是。此种扩容评估法做了一个假设,即服务所能够承载的 QPS 是和机器绝对线性增长的,只要机器充足,那么能够承载的 QPS 是没有上限的。但服务依赖的存储是有上限的,微服务能够提供的极限 QPS,其实是由它本身和它依赖的存储的最小值共同决定的。

以上述案例的压测值和损耗比为例,架构如下图 3 所示:

图 3:带存储的架构图

当前图示中部署了 100 台机器,理论上可以支撑 9000/s的QPS,但如果所依赖的存储只能支撑 5000/s的QPS,那么即使部署 100 台或者更多的应用机器,它能够承载的QPS 也不能线性增长,最大只能支撑到 5000/s的QPS。

因此,在实际压测中,除了寻找单机压测值和损耗比之外,还需要对微服务依赖的存储,以及除存储之外其依赖的其他微服务进行压测,寻找微服务压测中的最短板,进而确定微服务能够支撑的最大 QPS。

如何做写压测

读服务是无状态的,所以可以直接采用基于录制的压测方案进行压测。但是写服务是有状态的,因为录制的流量是用户在线上产生的真实请求,比如下单请求,如果直接使用录制的流量进行回放,可能会给客户的账号误下一笔订单,在生产环境中是不允许的。如果出现这样的线上操作,就算是线上事故了。

其实,保障相对高保真的写压测有以下两个常见的方式进行应对。

第一种是采用模拟账号进行替换或数据修改进行压测。

假设压测使用的数据是用户私有数据,比如压测发送微博的接口或提交订单的接口,就可以将录制数据里的用户账号替换为测试账号,这样压测时产生的微博和订单都隶属于测试账号,就不会对线上产生影响了。

此外,如果压测使用的数据是公有数据,比如新闻投稿接口,只要新闻投稿了所有用户都可见。对于这种公有数据的接口,可以在业务上进行处理,比如修改录制的新闻投稿数据,将所有的投稿都修改为待审核。这样压测产生的数据都处于待审核状态,在线上是不可见的,所以此种压测对线上不会产生影响。

第二种方式是采用压测数据打标 + 影子库的方式进行特殊处理,架构如下图 4 所示:

图 4:数据打标+影子库压测架构

上述架构里的数据打标和第一种里的数据修改是有区别的,它不会更改原始录制的任何数据,只是在压测的时候,对于压测模块发起的任何请求都增加一个标记,标记它为压测请求。

在业务应用模块识别此标识,如果识别出压测请求,则将压测请求的数据全部写入上图 4 中的影子库中。影子库中的数据不会暴露给外部查询以及用于进一步的生产,因此不会产生线上影响。对于微服务依赖的其他微服务提供的写接口,可以在压测时继续传递标识,被依赖的微服务也识别此标识,将压测数据写入影子库即可。通过标识传递+影子库的方式,即构建了一个线上写压测环境。

基于压测数据进行行动

压测过程中有两方面重要的数据,一个是压测过程中的各项指标数据,另一个是压测的结果即服务所能够支撑的QPS。

压测过程的各项指标数据有:压测时机器的CPU 利用率的变化、内存的变化、进程里各线程的CPU 利用率、微服务依赖的存储的CPU利用率、内存使用率等。压测过程中监控这些数据是为了发现系统瓶颈点,并快速优化,进而提升微服务能够支撑的QPS。这里简单列举一些可能存在的瓶颈点。

如果压测过程中,发现被压测应用的CPU 都被某一个或某一类线程消耗,同时通过堆栈信息,确定这个或这类线程的所有 CPU 消耗都集中在一个方法里。那么极大可能,这个方法里有十分消耗 CPU 的代码,可能是一个大对象的JSON 序列化或者是一段可以优化的多层嵌套 for 循环。

再比如,在只部署了一台应用机器和对应存储(MySQL)的情况下。理论上压测时,应该是单台应用机器的CPU 先达到 100%。但如果在实际压测中,是 MySQL 所在机器的CPU 先打满,那么很大概率上是被压测接口请求数据库的 SQL 是一个慢 SQL。引发这种情况的原因可能是未命中索引、一次请求的数量太多、存在 SQL 的深翻页等。此时,就需要对这些 SQL 进行调优,以便进一步提升微服务的性能。

压测的极限 QPS 除了让我们了解了微服务的最大支撑能力之外,另外一个作用就是参考此值来设置微服务的限流阈值。流量达到压测时的QPS 时,微服务的各项指标如 CPU、内存等,均已达到极限,为了保证微服务的稳定,需要将进入微服务的流量限制在压测的 QPS 之下。根据压测值设置限流时,有以下几点需要注意。

上述案例中,单机压测的 QPS为100/s。但限流时,不能直接设置单机限流阈值为 100/s,因为达到此QPS 时,机器的CPU 已经达到 100% 了。正常情况下,线上机器的 CPU利用率维持在 40%~50% 是安全的,再升高就需要扩容了。因此限流时,可以将压测的 QPS 适当打折,设置压测为 QPS*40%。

如果微服务提供不止一个接口,那么上述的限流阈值就还需要打折。比如微服务对外提供了两个接口,那么最简单的打折办法为:单机 QPS*40%*50%。

在前述的讲解中曾提到过,微服务能够支撑的 QPS是有上限的,并不是随着机器数量无限增长的。因此,除了设置单机级别的限流之外,还需要设置微服务集群维度的限流阈值。限流阈值的设置方法可以参考上述第 1、2 点。

本节总结

在这一讲里,讲解了如何构建高保真的压测环境。同时,针对写服务,详细介绍了如何通过优化升级来解决“写服务有状态”这一问题。

此外,压测过程中的数据和压测结果不只是用来记录,还可以用于分析,寻找可以优化的瓶颈点。其次,需要根据压测极限值,设置微服务的限流阈值,防止流量超过压测极限值,进而将机器打挂,导致服务完全不可用。

最后,再给你留一道讨论题,你当前所在团队的压测是如何开展的?欢迎留言区留言,我们一起讨论。

这一讲就到这里,感谢你学习本次课程,接下来我们将学习22 | 重构:系统升级,如何实现不停服的数据迁移和用户切量?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/585745.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LiveGBS user/save 逻辑缺陷漏洞复现(CNVD-2023-72138)

0x01 产品简介 LiveGBS是安徽青柿信息科技有限公司研发的一款国标(GB28181)流媒体服务软件,可提供提供用户管理及Web可视化页面管理,开源的前端页面源码;提供设备状态管理,可实时查看设备是否掉线等信息等。 0x02 漏洞概述 LiveGBS user/save 接口处存在逻辑缺陷漏洞,未…

【Qt之OpenGL】01创建OpenGL窗口

1.创建子类继承QOpenGLWidget 2.重写三个虚函数 /** 设置OpenGL的资源和状态,最先调用且调用一次* brief initializeGL*/ virtual void initializeGL() override; /** 设置OpenGL视口、投影等,当widget调整大小(或首次显示)时调用* brief resizeGL* param w* para…

请求接口报错:java.lang.IllegalStateException: argument type mismatch

目录 一、场景二、报错信息三、控制器四、接口调用五、原因六、解决 一、场景 1、调用后端接口报错 2、接口参数以Json方式传递 – 二、报错信息 java.lang.IllegalStateException: argument type mismatch Controller [com.xxx.huarunshouzheng.controller.MallControlle…

Ubuntu如何更换 PyTorch 版本

环境: Ubuntu22.04 WLS2 问题描述: Ubuntu如何更换 PyTorch 版本考虑安装一个为 CUDA 11.5 编译的 PyTorch 版本。如何安装旧版本 解决方案: 决定不升级CUDA版本,而是使用一个与CUDA 11.5兼容的PyTorch版本,您可…

75、堆-前K个高频元素

思路 这道题还是使用优先队列,是要大根堆,然后创建一个类,成员变量值和次数。大根堆基于次数排序。前k个就拿出前k的类的值即可。代码如下: class Solution {public int[] topKFrequent(int[] nums, int k) {if (nums null || …

解决: 0x803f7001 在运行Microsoft Windows 非核心版本的计算机上,运行“ slui.exe 0x2a 0x803f7001 “以显示错误文本,激活win10步骤流程。

一. 解决 0x803F7001在运行Microsoft Windows非核心版本的计算机错误 首先,按下winR打开"运行",输入 regedit 后回车,打开注册表。   然后再注册表下输入地址HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProt…

Electron+Vue3+Vite+ElectronForge整合 - 一键启动两个服务 一键打包两个服务

说明 本文介绍一下 Electron Vue3 Vite Electron Forge 的高级整合操作。vue3 : 使用 TS 的语法开发; Electron : 使用 JS 的语法开发。本文将从项目初始化开始,一步一步的完成项目的启动、打包全流程的介绍。实现的效果是 : 1、一个正常…

一个类实现Mybatis的SQL热更新

引言 平时用SpringBootMybatis开发项目,如果项目比较大启动时间很长的话,每次修改Mybatis在Xml中的SQL就需要重启一次。假设项目重启一次需要5分钟,那修改10次SQL就过去了一个小时,成本有点太高了。关键是每次修改完代码之后再重…

前端打包过大如何解决?

前端开发完毕部署到线上是,执行npm run build。当打包过大时,部署到服务端后加载缓慢,如何优化? 我们可以通过执行npm run analyze。可以看到各个包文件大小的区别。 当打包过大时,通过压缩gzip的方式,可以…

React路由导航

1. 什么是路由导航 一个路由跳转到另一个路由&#xff0c;并且在跳转的同时有可能需要传递参数进行通信&#xff0c;比如列表页跳转到详情页携带参数 2. 声明式导航 声明式导航是指通过在模版中通过 <Link/> 组件描述出要跳转到哪里去&#xff0c;比如后台管理系统的…

【LeetCode】---15.最小栈

【LeetCode】---15.最小栈 一、题目解析&#xff1a;二、算法原理&#xff1a;三、代码实现&#xff1a; 一、题目解析&#xff1a; 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

ARP学习及断网攻击

1.什么是ARP ARP&#xff08;Address Resolution Protocol&#xff09;是一种用于在IPv4网络中将IP地址映射到MAC地址的协议。在计算机网络中&#xff0c;每个网络接口都有一个唯一的MAC地址&#xff08;Media Access Control address&#xff09;&#xff0c;用于识别网络设备…

形态学图像处理

首先自己随便写了一个单词&#xff0c;然后在周围画一些相对细一点的噪声。 # 读取原始图片 original cv2.imread("romance.jpg") # 构造一个全1的5*5矩阵 kernel np.ones((5, 5), np.int8) 腐蚀 腐蚀&#xff08;Erosion&#xff09;是形态学图像处理中的一种基本…

Linux操作系统·进程管理

一、什么是进程 1.作业和进程的概念 Linux是一个多用户多任务的操作系统。多用户是指多个用户可以在同一时间使用计算机系统&#xff1b;多任务是指Linux可以同时执行几个任务&#xff0c;它可以在还未执行完一个任务时又执行另一项任务。为了完成这些任务&#xff0c;系统上…

初识Linux -- Linux的背景和发展史介绍

点赞关注不迷路&#xff01;&#xff0c;本节涉及初识Linux&#xff0c;主要为背景介绍和xshell登录主机。 1.Linux背景 1.1 发展史 Linux从哪里来&#xff1f;它是怎么发展的&#xff1f;在这里简要介绍Linux的发展史。 要说Linux&#xff0c;还得从UNIX说起。 1.2 UNIX发…

水下机器人(ROV)中继器(TMS)究竟是个啥?

前段时间公众号后台有人问释放ROV的装置&#xff0c;由于只用过观察级ROV Valor&#xff0c;博主一直以为他说的是绞车&#xff0c;后来才明白他说的是中继器&#xff0c;在水中用来释放、控制和回收ROV的装置。 中继器TMS的全称是缆绳管理系统Tether Management System&#…

Linux基础——Linux开发工具(下)_make/makefile

前言&#xff1a;在经过前面两篇学习&#xff0c;大家对Linux开发工具都有一定的了解&#xff0c;而在此之前最重要的两个工具就是vim&#xff0c;gcc。 如果对这两个工具不太了解&#xff0c;可以先阅读这两篇文章&#xff1a; Linux开发工具 (vim) Linux开发工具 (gcc/g) 首先…

vue 时间轴页面 自己的写法 欢迎交流指正

<div class"first-box"><!--贯穿线--><div class"vertical-line-wrap"><div class"vertical-line"></div><div class"vertical-line-arrow"></div></div><!--开始--><div c…

多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测

多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测 目录 多输入多输出 | Matlab实现WOA-LSSVM鲸鱼算法优化最小二乘支持向量机多输入多输出预测预测效果基本介绍程序设计往期精彩参考资料 预测效果 基本介绍 Matlab实现WOA-LSSVM鲸鱼算法优化…

我五一是这样计划的,第一天...

前言 这个时间点&#xff0c;大多数人一定已经“峡谷做好准备全军出击”或者在出行的路上了。这个时间我也在回老家路上聊一聊。 行程 老读者都知道我老家在内蒙的西北的边陲城市&#xff0c;往年票都是随便买、除了春运几乎坐不满&#xff0c;今年五一居然也需要抢票&#…