顾老师新书《全栈软件测试工程师宝典》
https://item.m.jd.com/product/10023427978355.html
以前两本书的网上购买地址:
《软件测试技术实战设计、工具及管理》:
https://item.jd.com/34295655089.html
《基于Django的电子商务网站》:
https://item.jd.com/12082665.html
3.3 性能调优
3.3.1分析方法
软件的性能调优的方法分为自顶向下和自底向上两种方法。
1.自顶向下分析法
自顶向下分析法是从顶部开始发现问题,然后逐步向底部深入挖掘。比如通过发现系统响应时间变慢,吞吐率减少,定位系统化存在性能问题,然后逐步查看底层去查看是什么原因导致的。
2.自底向上分析法
自底向上分析法是通过发现CPU占有率高、内存消耗大、磁盘I/O变慢或网络延迟从而定位系统化存在性能问题,然后逐步查看顶层的表现来查找性能的问题。
自顶向下和自底向上是分析性能问题的两种方法,这两种方法没有优劣,在性能分析的时候应该很好地结合使用这两种方法,从而快速地发现问题。
3.3.2前端优化
现在前端技术层出不穷,前端性能测试也越来被受到重视。目前关于前端性能测试调优,Yahoo提出的“Web前端性能测试35条规则”是最得到大家认可的,读者可以访问https://developer.yahoo.com/performance/rules.html去查看“Best Practices for Speeding UpYour Web Site”这篇文章。
3.3.3程序优化
程序优化包括:表单压缩、局部压缩、逻辑清晰、谨慎继承、算法优化、批处理、延迟加载、防止内存泄露、减少对大对象的引用、防止死锁、索引、存储过程、内存分配、并行、异步、好的模式设计、合适的I/O等诸多方面。性能测试工程师要配合开发工程师做好程序优化工作。
3.3.4配置优化
配置优化包括:JVM优化、连接池优化、线程池优化、缓存机制优化、CDN等几种方式。在这里简单介绍CDN。
以前中国的小朋友在线观看美国迪士尼的节目需要通过访问迪士尼总部的服务器来实现。虽然现在互联网速度非常快,但是在中国访问迪士尼在美国的官方服务器必定要通过中美海底光缆(CUCN),系统响应时间,可靠性等肯定是比较差的。在中国大陆建立了迪士尼的镜像服务器,每隔数小时把迪士尼在美国总部的节目同步到中国的镜像服务器中,中国的小朋友就可以通过镜像服务器观看迪士尼的节目了,虽然有数小时的延迟,比如在格林威治时间0:00美国主服务器上推出的节目,在中国可能要到格林威治时间6:00才可以看到,但是播放节目的速度,黄面的流畅性肯定要比在线观看在美国迪士尼总部服务器上的节目要好得多。请参看图3-39所示。
图3-39 CDN
3.3.5数据库优化
数据库优化包括:架构结构优化、共享SQL、查询器优化、SQL语句优化、单条/并行SQL、优化内存(SGA、PGA、AMM)以及优化IO。
3.3.6结构优化
随着云计算的大力发展。通过结构优化来提高软件性能,在软件研发中受到越来越大的重视。
1. 互联网架构演化
在谈论结构优化之前,先来看看互联网架构发展的历史。
最原始的互联网架构图如图3-40所示,这个时候后端仅仅存在Web服务器和数据库服务器,而且这两个服务器是处于同一条机器上的。
第二代互联网架构是Web服务器和数据库服务器处于一个单独的服务器中,如图3-41所示。
图3-40 最原始的互联网络结构
图3-41 Web服务器和数据库服务器分离
第三代互联网架构引入本地缓存和分布式缓存的模块,性能得到了提升,如图3-42所示。
第四代互联网架构引入了Nginx反向代理实现负载均衡,如图3-43所示。
图3-42 本地缓存和分布式缓存
图3-43 Nginx反向代理实现负载均衡
第五代互联网架构将数据库读写进行了分离,如图3-44所示。
第六代互联网架构数据库按业务分库,在这里分离了课件业务、购买业务以及其他业务,如图3-45所示。
图3-44 数据库读写分离
图3-45 数据库按业务分库
第七代互联网架构把数据库中的大表拆分成小表,如图3-46所示。
第八代互联网架构使用LVS或F5来使多个Nginx负载均衡,如图3-47所示。
图3-46 把大表拆分成小表
图3-47 使用LVS或F5来使多个Nginx负载均衡
第九代互联网架构通过DNS轮询实现机房间的负载均衡,如图3-48所示。
第十代互联网架构引入NoSQL数据库和搜索引擎等技术,如图3-49所示。
图3-48 通过DNS轮询实现机房间的负载均衡
图3-49 引入NoSQL数据库和搜索引擎等技术
第十一代互联网架构把大应用拆分为小应用,如图3-50所示。
第十二代互联网架构复用的功能抽离成微服务,如图3-51所示。
图3-50 把大应用拆分为小应用
图3-51 Nginx反向代理实现负载均衡
第十三代互联网架构把应用建立到云上。
互联网架构的改进使得产品的性能越来越好,但是千万不能认为只要加机器就可以解决性能问题的观念,有些问题,比如内存溢出,不是简单地通过加机器就可以解决的。
2. 虚拟节点
接下来看一下虚拟节点。分布式结构是由多台机器集成的,但是每台机器的性能往往是不相同的,如果不引入虚拟节点,每个机器承载的负载是相同的,如图3-52所示,任务通过m=rand(232)%4 1分配到1号机、2号机、3号机和4号机这四个节点上。这里1号机与2号机硬件性能比较好,3号机其次,4号机最差。所以可以这样建立虚拟节点,如图3-53所示。
图3-52 不带虚拟节点的分布式结构图
图3-53 带虚拟节点的分布式结构
1号机、2号机性能好,分配3个虚拟节点;3号机其次,分配2个虚拟节点;4号机最差,分配1个虚拟节点。这样分配公式变为m=rand(232)%9 1。性能好的机器分配到的任务概率比性能差的机器要高。
在看一种情况,随着业务需求的增长,要向虚拟节点中插入一台5号机器,如图3-54所示。
图3-54 在分布式结构中加入节点
图3-55 带虚拟节点的分布式结构
图3-56 在带虚拟节点的分布式结构中加入节点
由于存在“会话黏连效应”,以前分配给1号机、2号机、3号机、4号机上的任务不会由于加入新的物理机器而进行重新分配,比如,添加新节点前服务A1以前在1号机上运行,添加后服务A1仍旧会滞留在1号机上上。据说前几年京东发生的“缓存雪崩”事故就是这样造成的,加入了新的物理节点,但是没有引入虚拟节点,结果新节点没有被有效地利用,缓存溢出,从而造成事故。如果采取虚拟节点,当5号机器加入之前,服务在每个虚拟节点上分配如图3-55所示。当5号机器加入后,虚拟节点号是可以进行的重新分配的,而服务又仅仅与虚拟节点号绑定,所以加入新机器后,服务发生了重组,新加入的节点起到了分担服务的作用,如图3-56所示。。
3. MapReduce
MapReduce是一种大数据技术,其实分为Map和Reduce两个方法,它也是通过分布式提高性能的一种手段。假设现在有一套《大英百科全书》,要统计每个单词出现的次数,如果这个工作让单机来完场,显然是十分困难的。如果采用分布式架构,把《大英百科全书》的第1册第1章分配给1号机器处理、第1册第2章分配给2号机器处理、…、第2册第1章分配给m号机器处理…。所有的机器计算完毕汇总给另外一台机器进行总结,如图3-57所示。
图3-57 MapReduce
分发的过程使用了Map方法,汇总使用了Reduce方法。这样就大大提高了单机作业的速度。
3.3.7 JVM调优
在第3.2.5 节介绍了JVM性能监控,本节介绍一下JVM调优[29]。
(1)配置jstatd的远程RMI服务。
如果要看远程服务器上Java程序的GC情况需要执行这个步骤,允许JVM工具查看JVM使用情况。
将下面的代码存为文件jstatd.all.policy,放到%JAVA_HOME%/bin目录下,其内容如下。
代码语言:javascript复制grant codebase"file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
执行命令。
代码语言:javascript复制>jstatd-J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.0.12&
192.168.0.12为服务器的IP地址。
(2)jVisualVM控制台
执行%JAVA_HOME%binjvisualvm.exe,打开JVM控制台。通过菜单“工具->插件”中找到Visual GC插件进行安装。
(3)对要执行Java程序进行调优
以my.jar为例,在该jar包所在目录下建立一个start.sh文件,文件内容如下。
代码语言:javascript复制java -server -Xms4G -Xmx4G -Xmn2G -XX:SurvivorRatio=1-XX: UseConcMarkSweepGC -Dcom.sun.management.jmxremote-Dcom.sun.management.jmxremote.port=1100-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false -jar my.jar&
配置后,使用JVM控制台即可查看JVM(CPU/内存)及垃圾回收的状况。
(4) 控制台配置
打开jvisualvm.exe,通过菜单“远程->添加远程主机->输入远程IP->添加JMX连接”。
(5)JVM调优核心为调整年轻代、老年代的内存空间大小以及使用GC的类型。在start.sh文件内容。
首先确认这台机器是一个4G内存的机器。
•-Xms4G指JVM启动时整个堆(包括年轻代,年老代)的初始化大小。
•-Xmx4G指JVM启动时整个堆的最大值。
•-Xmn2G指年轻代的空间大小,剩下的是年老代的空间。
•-XX:SurvivorRatio=1是指年轻代空间的2个Survivor空间与Eden空间的大小比例。
官方通过增大Eden区的大小,来减少YGC发生的次数,有时虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,此时stop-the-world的时间较长,所以需要按照程序实际情况去调优。
•-XX: UseConcMarkSweepGC指使用GC的回收类型。这里是CMS类型,JDK1.7以后推荐使用 UseG1GC,被称为G1类型(或GarbageFirst)的回收器。
(6)当设定start.sh的参数值完毕后,执行./start.sh此时就可以启动了。
通过jvisualvm.exe中的Visual GC插件查看GC的图形,也可以在服务器上执行:jstat -gc <JID> 1000,看到每1秒钟Java进程号JID的GC回收情况。
代码语言:javascript复制# jstat -gc 15016 1000
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGCFGCT GCT
699008.0 699008.0 29980.4 0.0 699136.0 116881.62097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 118344.82097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 119895.52097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 121383.12097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
••S0C。
Survivor0区分配空间。
•S0U。
Survivor1区中已经使用的空间。
•EC。
Eden区中所使用的空间。
•EU。
Eden区的当前使用空间。
•OC。
老年代分配的空间。
•OU。
老年代当前使用的空间。
•PC。
持久代的分配的空间。
•PU。
持久代的当前使用的空间。
•YGC。
年轻代发送的次数。
•YGCT。
年轻代发送的总时长。因此每次年轻代发生GC,即平均每次stop-the-world的时长为YGCT/ YGC ,单位为秒。
FGC。
年老代回收的次数,或者成为FullGC的次数。
FGCT。
年老代发生回收的总时长。
GCT。
包括年轻代YGC及年老代FGC的总时间长。
通常结合图形或数据,可以看到当EU即将等于EC的时候,会发生YGC,所以YGC次数 1,YGCT时间会增加。
当发生YGC的时候,如果S0U或S1U区如果有任意一个区域为0的时候,此时YGC的速度很快,相反如果S0U或者S1U中都有数据,或相对满的时候,此时YGC的时间偏长,这就是因为S0/S1及Eden区的比例问题导致的。
(7)经过一定时间的调优,基本上可以使得YGC的次数非常少,时间非常快,很长时间,数天都不会发生FGC,JVM调优结束。
3.4 本章总结
3.4.1 介绍内容
•性能测试介绍
Ø性能测试的定义
Ø由于性能测试没做到位发生的缺陷
u奥运门票事件
u12306事件
u淘宝双11事件
u“艺术升”事件
Ø性能测试类型
u普通性能测试(Perfoemce Testing)
u负载测试(Load Testing)
u疲劳性测试(Stress Testing)
u强度测试(Strength Testing)
u配置测试(Configuration Testing)
Ø性能测试指标
u响应时间(Response Time)
u吞吐率(Throughput Rate)
u资源利用率(Resource Utilization)
u性能计数器(Performance Counter)
u并发用户数与在线用户数(Number of Concurrent Users、Number of Online Users)
u思考时间(Tinking Time)
Ø性能测试环境
Ø观察性能的四个维度
u从终端用户角度看性能
u从系统运维人员角度看性能
u从软件设计开发人员角度看性能
u从测试人员角度看性能
Ø性能测试的判断标准
Ø性能测试的场景
Ø性能测试的干系人
Ø负载测试的二分法找拐点法
Ø全链路压测
•性能监控
ØWindows的性能监控
uCPU
u内存
u磁盘I/O
u进程
u网络
ØLinux的性能监控
uCPU
u内存
u磁盘与文件
u网络
u性能监控工具nmon
ØTomCat的性能监控
ØMySQL监控
ØJVM性能监控
u年轻代与年老代中没有被回收的数据块存储
u元空间
ujps
ujstat
u jVisualVM & jmap
ØAPM工具简介
uPinpoint
uSkyWalking
uZipkin
uCAT
•性能调优
Ø分析方法
u自顶向下分析法
u自底向上分析法
Ø前端优化
Ø程序优化
Ø配置优化
Ø数据库优化
Ø结构优化
u互联网架构演化
u虚拟节点
u MapReduce
ØJVM优化
3.4.2 案例