传统性能测试更多的是以事务为核心,更多的是由单个或者多个事务构成业务场景进行压测。全链路压测指彻底引入相关联的系统,尽可能真实模拟线上硬件环境,更多的是以请求为核心,彻底模拟真实请求流量,经过引流等方式进行场景的模拟进行压测,更多的适用于业务链路较长的交易。全链路一直是性能测试中的难点,其包含系统越多测试难度就越大,系统架构中每增长一层的监控内容就会给分析带来几何倍数的难度。所以,微服务架构下的性能测试的重要性就不言而喻了。前端
微服务系统系统间调用关系复杂,当出现业务流量暴涨的状况从CDN、网关接入、前端、缓存、中间件、后端服务、数据库整个交易链路都会面临巨大的访问压力,此时业务系统除了收到自身的影响还会依赖其余关联系统的状况,若是某一点出现问题,系统会累加问题并影响到其余其余系统,到时候是哪一个系统出问题谁也说不出清楚,好比当某系统MQ开始出现积压,下游系统处理能就可能会变慢,当MQ吃掉内存并形成宕机,整个链路交易都会中止。java
若是在测试环境进行全链路压测,最大难点在于没法评估用户从客户端登陆到完成交易的整个链路中,系统能的最大承载能力是多少。若是没法承载生成中的流量形成系统宕机,就会有灾难性的后果。因此在测试环境进行全链路要结合历史生成流量,并合理作出业务增加预估,若是能知足此流量能够断定为生产环境知足性能要求。固然,这只是权宜之计,若是在生产环境作全链路压测不会出现此状况。node
另外,全链路压测涉及的微服务模块多,开发组多,各组开发人员又各负责本身的模块,由于版本升级块,业务层架构变化也快,很难能了解清楚最新的架构,若是漏掉一个系统的调用关系,分析就会变得很是困难。ios
软件的版本控制问题,由于版本升级快,形成测试环境与生成环境代码版本不一致,数据库表结构和索引不一致的状况。这种状况会形成测试结果不许确,重复测试。多系统更难控制此状况。shell
开展全链路压测,除了传统性能测试的需求调研、环境准备、脚本开发、数据预埋、场景设计、场景执行、应用监控分析、瓶颈定位、瓶颈修复、回归测试、结果整理、输出报告等环节外还要加入分析需压测业务场景涉及系统和协调各个压测系统资源两个环节。数据库
一、梳理核心链路后端
在压测前咱们必定要首先分析清楚须要压测的业务场景,只有分析清楚了业务场景才能梳理出来涉及的相关系统,分析清楚后也能够更快的找到性能瓶颈进行系统优化。这个工做通常是由架构师来梳理并确认涉及的相关系统,梳理清楚后就能够反馈给压测负责人进行人员和资源的协调了。缓存
二、压测资源协调服务器
在全链路压测过程当中,最难的工做其实不是系统优化、压测环境搭建等技术工做,最难的是压测资源的协调工做。这里的资源不仅仅指压测硬件、软件、环境等资源,还包括了人力资源。架构
三、构建数据
数据的真实和可用是保证压测结果的关键,尽可能使数据多元化,参数重复性低,能够采用生产数据脱敏的方式。数据的真实性能够保证更真实的模拟生产数据流量。数据的真实不光指发起的数据,测试数据库的铺底数据量也要与生产一致。
四、流量监控
搭建流量监控平台,收集生产各类业务的流量,统计数据,按比例进行流量回放。
五、容量评估
首先知道容量目标是多少,好比所有交易量预期目标天天1亿笔,按流量平台监控到的业务占比进行压测,这样咱们能够清楚在哪一个节点应该增长多少机器,既能保证系统的稳定又能避免浪费。容量评估不是一步完成的,目标须要结合历史数据和公司现有业务规模。第一步先按现有环境摸底测试,再逐步增长或减小机器,循环屡次,最后达到精准的容量评估。
一、单系统优化
把链路中逐个环节尽可能切分红小块,粒度越小越佳,单粒度分析,涉及其余系统加挡板,这样能够基本解决全部性能问题。缺点是性能周期长。
二、架构优化
分析系统架构,在硬件资源不饱和状况下尽可能减小架构层。笔者在测试中遇到一个案例,A系统调用加解密服务器,A系统因特殊缘由线程固定300,不能增长线程,并发线程为300时,A系统服务器CPU为60%,TPS为370左右,CPU资源不饱和,加解密服务器cpu为50%,也不饱和,但因A系统不能调整线程数量,因此把加解密服务的包部署在A系统上,此时300并发,A服务器CPU为100%,TPS为700左右。这样的好处是减小了一层系统调用的链接时间,数据传输时间,又能使硬件充分利用,减小硬件的浪费。
三、业务优化
不少开发人员都会将优化思路集中在架构层面,可是不少时候从业务流程上进行优化效果可能更好,并且提高的效果会很是明显。业务优化不包括业务流程自己,还包活实现业务的代码逻辑,此优化场景多用于跑批业务。
下面我将分享在性能测试中,经常使用的具体分析系统瓶颈的几个方法。
应用系统从性能角度分为CPU密集型应用和IO密集型应用,调优的目标是让硬件达到瓶颈而不是软件达到瓶颈,最直观的体现就是TPS上升和监控到的CPU和IObusy使用率达到100%。除非有特殊要求,不然尽量使硬件使用率高。
CPU不饱和缘由有不少,最经常使用的分析手段是查看线程信息。
一、 jps命令查看java进程pid
二、jstack -l 5599 > 5599.tdump 把线程信息存进一个后缀为tdump的文件里,这里后缀txt也能够,我习惯用jvisualvm打开,因此后缀是tdump
三、sz 5599.tdump 把文件下载到本地
四、打开文件,查看线程信息,有三种状况:
4.1. 若是线程都是RUNNABLE状态,此时CPU利用率依然不高,说明线程池业务线程数量少,加大线程池线程数量。
4.2.若是线程状态是BLOCKED,要查该线程等待的锁编号。
4.3.根据锁编号找到持有锁的线程,再根据信息分析代码问题并优化。
此应用CPU利用率上不去的缘由是由于须要压缩的文件过大,压缩时间长,致使其余线程都在等待该线程释放锁,CPU同时间只能处理这一个线程,因此利用率低。
五、若是线程状态是WAITING,要分析是什么缘由致使线程等待:
这个线程是由于logback为同步线程锁,线程等待日志写入硬盘,致使CPU利用率上不去,只要把logback改为异步就能够了。
六、IO的问题有两种状况,一种是CPU等待IO;一种是单个磁盘IObusy达到100%,其余磁盘空闲。第一种状况能够采用缓存、异步的方式去解决,这样能解决大部分性能问题。这里主要介绍第二种状况,第二种状况能够进行业务层面的IO分散来保证。就是把写入一个磁盘的文件分散写到多个磁盘上,这样就能够缓解单个磁盘的压力。对于性能人员来讲,要定位到具体是哪一个文件致使的IO繁忙程度高。在代码的逻辑清晰的状况下,是彻底能够知道哪些文件是频繁读写的。可是对性能分析人员,一般是面对一个不是本身编写的系统,有时仍是多个团队合做产生的系统。若是能够迅速地把问题到一个段具体的代码,到一个具体的文件,那就能够提升沟通的效率。
iostat命令能够发现IO异常。iotop能够定位具体哪一个进程致使io异常。但要定位到具体文件,咱们须要先了解一个文件的重要属性:inode。
理解inode,要从文件储存提及。文件储存在硬盘上,硬盘的最小存储单位叫作"扇区"(Sector)。每一个扇区储存512字节(至关于0.5KB)。操做系统读取硬盘的时候,不会一个个扇区地读取,这样效率过低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最多见的是4KB,即连续八个 sector组成一个 block。
[root@cdhslave1 ~]# tune2fs -l /dev/sda3|grep Block
Block count: 66891008
Block size: 4096
Blocks per group: 32768
复制代码
文件数据都储存在"块"中,那么很显然,咱们还必须找到一个地方储存文件的元信息,好比文件的建立者、文件的建立日期、文件的大小等等。这种储存文件元信息的区域就叫作inode,中文译名为"索引节点"。inode包含文件的元信息,具体来讲有如下内容:
1. 文件的字节数
2. 文件拥有者的User ID
3. 文件的Group ID
4. 文件的读、写、执行权限
5. 文件的时间戳,共有三个:ctime指inode上一次变更的时间,mtime指文件内容上一次变更的时间,atime指文件上一次打开的时间。
6. 连接数,即有多少文件名指向这个inode
7. 文件数据block的位置
经过inode就能找到具体文件,监控inode,我用SystemTap这个工具。
SystemTap是一个诊断Linux系统性能或功能问题的开源软件。它使得对运行时的Linux系统进行诊断调式变得更容易、更简单。下图是Systemtap的工做原理:
Systemtap的运行是在内核层面,而不是shell层面。Systemtap自带的examples中有监控IO的例子,以iotop.stp为例,执行的结果是:每隔5秒打印读写总量排前10位的进程。先写一个命令dd bs=64k count=40k if=/dev/zero of=test oflag=dsync,这个命令是每次从/dev/zero 读取64k数据,而后写入当前目录下的test文件,一共重复4万次。执行命令后打开iotop.stp监控,以下图:
能够看到读写最多进程。可是现有脚本不能看到dd命令读文件和写文件的inode,须要本身扩展一下脚本,脚本扩展后以下图:
这里就能够看到咱们读文件的inode为4072,写文件的inode为15,经过find / -inum命令能够找到具体写哪一个文件。
本篇介绍了全链路压测的概念,微服务架构下全链路压测的意义、难点以及如何作全链路压测,最后给出系统瓶颈分析和调优建议和方法。