高手的存在,就是让服务10亿人的时候,你感觉只是为你一个人服务......

性能测试指南

目录
  1. 1. 引言
  2. 2. 性能测试的概念
  3. 3. 术语
    1. 3.0.1. 并发用户数
    2. 3.0.2. 响应时间
    3. 3.0.3. 吞吐量
    4. 3.0.4. 每秒处理事务数(TPS)
    5. 3.0.5. 点击率
    6. 3.0.6. 事务成功率
    7. 3.0.7. 并发
  • 4. 性能测试类型
    1. 4.1. 性能测试
    2. 4.2. 负载测试
    3. 4.3. 压力测试
    4. 4.4. 稳定性测试
  • 5. 性能测试基本流程
    1. 5.1. 性能需求分析
      1. 5.1.1. 性能需求评估
    2. 5.2. 性能测试准备
    3. 5.3. 执行性能测试
    4. 5.4. 结果分析与性能调优
    5. 5.5. 性能报告与总结
  • 6. 性能测试模型
    1. 6.1. taobao性能模型分析
      1. 6.1.1. PV->TPS转换模型
      2. 6.1.2. TPS->并发用户数
    2. 6.2. 网银在线性能模型分析
      1. 6.2.1. TPS计算公式
    3. 6.3. 我们的性能测试模型
  • 7. 环境搭建
    1. 7.1. 按容量配比机器
    2. 7.2. 依据拓扑图准备机器资源
    3. 7.3. 搭建应用环境
    4. 7.4. 数据准备
  • 8. 压力工具选择
  • 9. 性能分析
    1. 9.1. 分析思路:
    2. 9.2. 常见性能问题参考
  • 10. 性能调优
    1. 10.1. 性能调优目标与策略
    2. 10.2. 调优的基本步骤
    3. 10.3. 配置项性能调优参考
      1. 10.3.1. Linux系统调优
      2. 10.3.2. JVM 调优
      3. 10.3.3. Nginx 调优
      4. 10.3.4. MySQLInnoDB调优
  • 11. 基础指标
    1. 11.1. 响应时间
    2. 11.2. 事务成功率
    3. 11.3. 负载机的资源利用率
    4. 11.4. 应用服务器硬件性能指标
  • 12. 性能监控
    1. 12.1. JVM监控工具
      1. 12.1.1. jvisualvm
      2. 12.1.2. jinfo
      3. 12.1.3. jstack
      4. 12.1.4. jmap
      5. 12.1.5. jprofile
    2. 12.2. linux命令监控
    3. 12.3. nmon
    4. 12.4. 文件句柄数查看及修改
  • 13. 数据库分析与诊断工具
    1. 13.1. oracle
  • 14. 前端性能测试
  • 平时做性能测试工作,经常拜读性能著作,taobao的白皮书,京东的性能测试指南等,
    常常翻阅,有所感悟,在此整理一番,以备后用。


    引言

    性能测试指南的目的在于授人以渔而不是授人以鱼,通过在此指引下,能够独立完成性能测试,
    掌握性能测试过程中所需要的工具、技能、方法等。积累相关的性能测试经验,并提升测试人员自身的技能。


    性能测试的概念

    在正常、峰值以及异常负载条件下,测试系统的各项性能指标。
    通过自动化的测试工具模拟进行。


    术语

    并发用户数

    在同一时刻与服务器进行了交互的在线用户数量

    响应时间

    客户发出请求到得到响应的整个过程的时间。一般他可以分为三部分:呈现时间,数据传输时间和系统处理时间

    吞吐量

    一次性能测试过程中网络上传输的数据量的总和

    每秒处理事务数(TPS)

    每秒钟系统能够处理事务或交易的数量,它是衡量系统处理能力的重要指标。

    点击率

    点击率可以看做是TPS的一种特定情况。每秒钟用户向web服务器提交的HTTP请求数。

    事务成功率

    本次测试中出现成功的事务数量/事务的总数

    并发

    并发分为狭义和广义两类。
    狭义的并发,即所有的用户在同一时刻做同一件事情或操作,这种操作一般针对同一类型的业务,或者所有用户进行完全一样的操作,比如双11的秒杀活动,目的是测试数据库和程序对并发操作的处理。
    广义的并发,即多个用户对系统发出了请求或者进行了操作,但是这些请求或操作可以是不同的。对整个系统而言,仍然有很多用户同时进行操作,大多数场景都是广义并发,比较接近用户在系统上的操作行为。
    做性能测试时,一般先做广义并发,再做狭义并发。


    性能测试类型

    在做性能测试之前,需要明白以下4中测试类型。

    1.性能测试。
    2.负载测试。
    3.压力测试。
    4.稳定性测试。

    我们的系统随着单位时间流量的不断增长,压力不断增大,服务器资源会不断被消耗,TPS值会因为这些因素而发生变化,而且符合一定的规律。(建议看看理发师模型
    Alt text

    a点:性能期望值
    b点:高于期望,系统资源处于临界点(eg.cpu 50%,load:cpu*0.7)
    c点:高于期望,性能处于拐点
    d点:超过负载,资源不够用,系统处于崩溃

    性能测试

    a点到b点之间的系统性能

    简述:
    性能测试是指通过模拟生产运行的业务压力量和使用场景组合,测试系统的性能是否满足生产性能要求。
    目的:
    验证系统是否有其要求达到的能力。
    特点:
    对系统性能已经有了解的前提,对需求有明确的目标,并在已经确定的环境下进行的。
    关注点及产出
    关注的是系统性能是否和具体的性能需求相一致,而当系统性能超过性能需求的时候,系统的表现并不是测试人员关心的重点。

    负载测试

    b点的系统性能

    简述:
    狭义的负载测试,是指对系统不断地增加压力或增加一定压力下的持续时间,直到系统的某项或多项性能指标达到安全临界值,例如某种资源已经达到饱和状态等。
    目的:
    找到系统处理能力的极限。了解系统的性能容量,或是配合性能调优来使用。
    关注点及产出
    1.得出线下系统最有TPS。
    2.得出线下系统最有TPS时系统资源利用率。
    3.得出线下系统极限并发数。

    压力测试

    b点到d点之间

    简述:
    是指超过安全负载的情况下,对系统不断施加压力,是通过确定一个系统的瓶颈或不能接收用户请求的性能点,来获得系统能提供的最大服务级别的测试
    目的:
    检查系统处于大压力性能下时,应用的表现。
    特点:
    一般通过模拟负载等方法,使得系统的资源使用达到较高的水平。
    关注点及产出
    发现功能测试不能发现的非功能性缺陷。
    1.得出线下系统崩溃点的TPS。
    2.得出线下系统崩溃时资源使用率
    3.得出线下系统极限并发数

    稳定性测试

    c点的系统性能

    简述:
    在给系统加载到性能拐点(tps最大值)情况下,使系统运行一段时间(一般为4小时),以此检测系统是否稳定。
    目的:
    主要目的是验证是否支持长期稳定的运行。
    关注点及产出
    关注系统稳定性。
    得出系统稳定状态下的资源利用、连接池、TPS、响应时间、DB健康情况等数据。


    性能测试基本流程

    性能测试工作开展流程,见图:
    Alt text

    性能需求分析

    性能需求分析是整个性能测试工作开展的基础,如果连性能的需求都没弄清楚,后面的性能测试工具以及执行就无从谈起了。
    在这一阶段,性能测试人员需要与项目人员进行沟通,同时收集各种项目资料,对系统进行分析,确认测试的目标。并将其转化为可衡量的具体性能指标。

    性能需求评估

    项目组人员对性能测试业务点没有很好的概念,判断是否进行性能测试可以从以下几个方面进行思考:

    1. 从业务角度来分析。
      如果一个项目上去后使用的人数比较多,量比较大,就有做性能测试的必要,反之,如果一个项目上线后,没有几个人在用,无论系统多大,设计如何复杂,并发性的性能测试是没有必要做的,前期可以否决。
    2. 从系统架构角度来分析。
      如果一个系统采用的框架是老的系统框架,只是在此框架上增加一些应用,其实是没有必要做性能测试。如果一个系统采用的是一种新的框架,可以考虑做负载测试。
    3. 从实时性角度来分析。
      如果一个项目要求某个功能的响应时间,这个有作并发测试的可能性,在大并发量的场景下,查看这个功能的响应时间。
    4. 从数据库角度分析。
      很多情况下,性能测试是大数据量的并发访问、修改数据库,而瓶颈在于连接数据库池的数量,而非数据库本身的负载、吞吐能力。这时,可以结合DBA的建议,来决定是否来做性能测试。

    如果要进行性能测试,接下来我们就需要确定相应的性能点。主要从以下 4 个维度进行确定:

    1. 关键业务。
      首要维度,是确定被测项目是否属于关键业务,有哪些主要的业务逻辑点,特别是跟交易相关的功能点。
    2. 日请求量。
      如果日请求量很高,系统压力很大,而且又是关键业务,该项目需要做性能测试;而且其关键业务点,可以被确定为性能点。
    3. 逻辑复杂度。
      如果一个主要业务的日请求量不高,但是逻辑很复杂,则也需要通过性能测试。原因是,在分布式方式的调用中,当某一个环节响应较慢,就会影响到其它环节,造成雪崩效应。
    4. 运营推广计划。
      未雨绸缪、防患于未然、降低运营风险是性能测试的主要目标。被测系统的性能不仅能满足当前压力,更需要满足未来一定时间段内的压力。因此,事先了解运营推广计划,对性能点的制定有很大的作用。
      例如,运营计划做活动,要求系统每天能支撑多少 PV、多少 UV,或者一个季度后,需要能支撑多大的访问量等等数据。
      5.其它
      例如,当一个功能点不满足以上 4 个维度,但又属于内存高消耗、CPU高消耗时,也可列入性能测试点行列。

    最终,需要明确以下几点:
    1.测试业务点,细化到每一步骤
    2.测试环境搭建(项目组提供还是性能测试人员搭建),测试环境与正式版按比例配置,配置文件同正式版
    3.测试指标:TPS、并发用户数、响应时间等
    4.测试数据,按正式版配比,参数化数据至少为并发数的2倍,由项目组准备数据
    5.测试类型确定:至少做性能测试和稳定性测试,其他测试类型需要确认。
    6.测试时间点

    性能测试准备

    主要包括:设计场景,根据场景编写程序、编写脚本、准备测试环境,构造测试数据,环境预调优等;
    测试数据的设计也是一个重点且容易出问题的地方。生成测试数据量达到未来预期数量只是最基础的一步,更需要考虑的是数据的分布是否合理,需要仔细的确认程序中使用到的各种查询条件,这些重点列的数值要尽可能的模拟真实的数据分布, 否则测试的结果可能是无效的。
    预调优指根据系统的特点和团队的经验,提前对系统的各个方面做一些优化调整,避免测试执行过程中的无谓返工。比如一个高并发的系统,10000人在线,连接池和线程池的配置还用默认的,显然是会测出问题的。

    执行性能测试

    执行阶段工作主要包含两个方面的内容:一是执行测试用例模型,包括执行脚本和场景;其次测试过程监控,包括测试结果、记录性能指标和性能计数器的值

    结果分析与性能调优

    发现问题或者性能指标达不到预期,及时的分析定位,处理后重复测试过程。性能问题通常是相互关联相互影响的,表面上看到的现象很可能不是根本问题,而是另一处出现问题后引起的反应。这就要求监控收集数据时要全面,从多方面多个角度去判断定位。调优的过程其实也是一种平衡的过程,在系统的多个方面达到一个平衡即可。

    性能报告与总结

    编写性能测试报告,阐明性能测试目标、性能结果、测试环境、数据构造规则、遇到的问题和解决办法等。并对此次性能测试经验进行总结与沉淀。

    上面所有内容中,如果排除技术上的问题,性能测试中最难做好的,就是用户模型的分析。它直接决定了压力测试场景是否能够有效的模拟真实世界压力,而正是这种对真实压力的模拟,才使性能测试有了更大的意义。可以说,性能测试做到一定程度,差距就体现在了模型建立上。
      至于性能问题的分析、定位或者调优,很大程度是一种技术积累,需要多方面的专业知识。


    性能测试模型

    以下引用taobao和网银在线模型分析方法,基本思路都一样。

    taobao性能模型分析

    PV计算模型
    为了让性能测试的PV计算更接近生产线真实情况,利用现有最新的数据得出性能测试PV的计算公式。
    首先,通过http://monitor.taobao.com采集现有数据,下图所示的是任意选择一天得到的分布图, 6:00AM到次日的6:00AM,共24小时。
    Alt text

    经过长期监控,发现任何一天的分布图都与上图类似,故将这种分布视为整个淘宝网的浏览量分布。
    其次,进行数据统计:为了和目前真实情况更接近,选择最近一段时间的数据分布来做样本,
    记录下系统能够监控到的最短时间间隔的数据,考察其值的走势,并且找出每一天的最大值,抽样出每个时刻的值与当天最大值的比例,以此比例值的趋势,得出数据分布趋势,如下图所示:
    监控系统最精确可以采集到每3分钟的数据,一天24小时可以采集到480个点
    Alt text

    采用微积分思想,将每个时间点视为一个矩形,可以通过求和的方式求出整个分布图的面积,如下图所示:
    Alt text

    根据80/20原理,找出占据总体面积80%所用的时间,再计算出平均PV量。
    选择尽可能大的点计算出占据总体80%的面积,发现点的个数是240,那么意味着此时间长度为总时间长度的50%,则80/20原则在此可以转换成80/50原则,则有
    每台服务器每秒平均PV量 = (80%总PV)/(246060(240/480))/服务器数量。
    整理后得:每台服务器每秒平均PV量 = (1.6总PV)/ (2460*60) /服务器数量。进而计算出占总面积80%的PV平均值与整个图中的最高峰值的比,可以得出最高峰的PV量是1.2倍的平均PV量
    即 每台服务器每秒高峰PV量 = (1.21.6总PV)/(246060) /服务器数量。
    整理后得: 每台服务器每秒高峰PV量= (1.92总PV)/(2460*60) /服务器数量

    PV->TPS转换模型

    为了使PV在性能测试环境下可量化,根据PV的概念,通过以下方式将其转换成TPS。

    1.性能测试脚本中,只保留与性能点相关的内容,异步处理的,保留多个请求,从而确保压力目标。
    2.在执行场景中,不模拟浏览器缓存,确保每次请求都到达应用服务器,使得LoadRunner的一个请求等同于一个PV。
    3.在执行场景中,每次迭代,都模拟一个新用户,而且清除用户缓存信息,确保每个用户每次发送请求都是全新的。

    结论:通过以上三步,将PV转化成性能测试工具可识别的TPS。换言之,1PV=1TPS。

    TPS->并发用户数

    根据公式:并发用户数=TPS/响应时间,项目组给出响应时间,然后计算出并发用户。

    网银在线性能模型分析

    根据支付宝订单数来做建模demo:

    双11当天,支付宝的订单数是1.8亿笔,意味着每小时订单数达到1.8亿 / 24 = 750万笔,也意味着每秒订单数达到750万 / 3600 = 2083笔

    首先,让我们先来看看吞吐率指标(TPS),假设支付宝有100台前置服务器,分到每台机器就是每秒处理订单2083笔 / 100 = 20笔。

    这是不是意味着只要单台服务器的性能达到20 tps,我们的线上服务就足以支撑每天1.8亿的交易量呢?
    答案显然不是

    我们先来看看淘宝网每天交易量分布图:
    Alt text

    可以看到,交易量并不是24小时平均分布的,从早上8点开始到晚上12点才是交易量发生的主要时间段,也就是说实际上每天只有2/3的时间(16小时)才是有效时间。我们的性能指标应该调整到20tps * 150% = 30tps。

    即使是16个小时中,交易量也不是平均的,在午饭和晚饭时间会出现两个波谷,晚上8点到11点之间是一天的最高峰。最高峰大约是平均值的1.2倍,如果我们不想损失掉高峰时期的交易量的话,我们的吞吐率指标需要再上调到30tps * 1.2 = 36tps。

    以上只是一个普通日子的交易量分布情况,如果有某些重大活动事件,比如限时抢购、定时秒杀等活动,那么我们很可能在短时间承受几倍甚至十几倍的压力。如下图是京东某年某活动当天的交易量分布图:
    Alt text
    总体交易量是平日的几倍到十几倍,交易量从零点开始就达到一个小高峰,凌晨2点后逐渐降到冰点,早上8点又开始了一天的持续热度,
    下午7点出现一个小波谷紧接着就迎来了晚上11点左右的最高峰。对于这种特别庞大的活动我们需要提前做好性能预案,以往的数据就是我们最好的参考。

    通常来讲,我们对于系统的性能要求在每天高峰时期的1.5倍到4倍,如果按2倍计算,那么我们的吞吐率指标就继续上调到 36tps 2 = *72tps

    好了,单台服务器的性能达标了72tps。但是100台服务器加起来就能承载 72tps * 100 = 7200tps吗?

    比较难,这依赖于我们的负载均衡算法。假设我们有一个还不错的算法,但也不能保证长时间绝对的公平,所以单台服务器还需要做好压力波动的缓冲,
    如果按1.5倍计算,这样我们的指标又要上调到72tps150% = *98tps

    这里,我们已经把对单台服务器的性能指标从20tps逐渐上调到近100tps,是原来的5倍。当然这里还远没有结束。这1.8亿笔只是单一的下单操作的PV,
    假设用户每下单一笔,需要伴随着10次查询,3次提交,那么我们的服务器需要再评估其他或查询或提交的性能。假设这些其他附带请求的压力总和可能还得增大5倍,即达到98tps 5 = *500tps

    TPS计算公式

    线下单机基线TPS =线上日均交易量 / 86400 / 机器数 160% F

    注:86400为一天的秒数。
    注:假设硬件软件环境条件大致相同。
    注:F为影响因子,默认为1 。

    关键系数160%的由来,简单点讲就是在每天约50%的时间里完成了80%的工作,80% / 50% = 160%。

    该公式还只是最简单场景的抽象,真实的情况可能会很复杂(详见前面的数据示例分析),不过作为线下基线TPS来讲具备很重要的参考意义。

    线下基线TPS代表着为了达到线上的交易量,我们线下至少应该满足的性能指标。我们在做性能测试和评估的时候,基线TPS是一定要体现并首先要达到的目标。

    影响因子F是一个经验值,也是需要不断调优的,线上与线下的软硬件环境不同都会导致F值的变化,甚至不同的业务线可以有不同的值。当我们的性能沙箱建立、性能闭环成型之后,会更加稳定下来。

    我们的性能测试模型

    从上面taobai和网银在线的模型分析过程,总结下来:

    1.线上pv数据统计
    数据可以找产品人员或者BI人员,爬虫的数据也包括在内。
    2.根据pv分布图计算基线TPS
    先按照8/2原则,20%的时间完成80%的事务,找出80%所用的时间,调整8/2比例(8/3,8/4,8/5…..)。
    单机基线TPS=线上PV总量 80%/ 8640020% / 机器数 。(20%按照实际数值)
    3.计算峰值tps
    计算出占总面积80%的PV平均值与整个图中的最高峰值的比,比如taobao是1.2倍
    TPS=TPS基线1.2
    通常来讲,我们对于系统的性能要求在每天高峰时期的2倍,那么我们的TPS=TPS基线
    1.22
    即,** 最终TPS=(线上PV总量
    80%/ 8640020% / 机器数) 1.2 2 *


    环境搭建

    环境搭建最理想的情况:
    拓扑图同线上,软硬件资源同线上,数据同线上。
    但是基本上不可能有这种资源。我们需要按照线上的环境部署情况按比例缩减。

    按容量配比机器

    比如线上6台机器,实际没有这么多机器资源,可不可以按照1:1缩减,缩减为2台机器,相应的流量也缩减3倍。
    需要做容量规划的测试
    Alt text
    上图是根据xyz的机器配比做的容量规则,可以看到:机器数量跟并发用户数基本是整倍数增加,我们可以看做是1:1的增加,即并发用户增加一倍,机器数量增加一台。
    结论:一般情况,可以按照1:1缩减。

    依据拓扑图准备机器资源

    按照线上机器缩减的配比准备拓扑图和机器,
    Alt text

    服务器配置:

    Cpu:8核(4*2) Intel(R) Xeon(R) CPU E5620 @ 2.40GHz
    内存:8G
    磁盘:30G

    搭建应用环境

    web服务器,应用服务器、中间件、数据库跟线上的版本和配置保持一致,可以跟运维要配置文件。

    数据准备

    基础数据从线上导入,保证数据量的充分性,参数化的数据(比如账号密码),需要至少准备并发用户数的2倍,用于模拟缓存。


    压力工具选择

    常用的性能测试工具有:loadrunner11 ,jmeter,gatling ,apache ab,按需选择。
    多数情况下使用的是loadrunner。

    自动化性能测试可以采用:
    Jenkins+ansible+Gatling的方式。


    性能分析

    分析思路:

    分析过程
    在分布式架构下,性能瓶颈分析也变得相对困难。针对不同的应用系统、不同的测试目标、不同的性能关注点,根据性能指标的表现,采用“拆分问题,隔离分析”的方法进行分析,即逐步定位、从外到内、从表及里、逐层分解、隔离排除。
    可按以下顺序:

    日志分析—>服务器硬件瓶颈—〉网络瓶颈(对局域网,可以不考虑)—〉服务器操作系统瓶颈(参数配置)—〉中间件瓶颈(参数配置,web服务器等)—〉数据库及应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)。

    基于上述思想的指导,在具体执行层面,可以参考如下分析过程:

    1. 先看CPU利用率,如果CPU利用率不高,但是系统的Throughput和Latency上不去了,这说明我们的程序并没有忙于计算,而是忙于别的一些事,比如IO。(另外,CPU的利用率还要看内核态的和用户态的,内核态的一上去了,整个系统的性能就下来了。而对于多核CPU来说,CPU 0是相当关键的,如果CPU 0的负载高,那么会影响其它核的性能,因为CPU各核间是需要有调度的,这靠CPU0完成)
    2. 然后,我们可以看一下IO大不大,IO和CPU一般是反着来的,CPU利用率高则IO不大,IO大则CPU就小。关于IO,我们要看三个事,一个是磁盘文件IO,一个是驱动程序的IO(如:网卡),一个是内存换页率。这三个事都会影响系统性能。
    3. 然后,查看一下网络带宽使用情况,在Linux下,你可以使用iftop,iptraf,ntop,tcpdump这些命令来查看。
    4. 如果CPU不高,IO不高,内存使用不高,网络带宽使用不高。但是系统的性能上不去。这说明你的程序有问题,比如,你的程序被阻塞了。可能是因为等那个锁,可能是因为等某个资源,或者是在切换上下文。

    通过了解操作系统的性能,我们才知道性能的问题,比如:带宽不够,内存不够,TCP缓冲区不够,等等,很多时候,不需要调整程序的,只需要调整一下硬件或操作系统的配置就可以了。

    常见性能问题参考

    操作系统类

    Sys的CPU使用率过高
    User的CPU使用率过高,持续大于80%以上
    可用物理内存不足导致内存溢出
    磁盘空间不足导致交易处理失败,性能下降
    TCP/IP连接数限制导致用户请求失败
    磁盘IO使用比较繁忙,持续大于70%

    中间件类

    常用主流中间件:Tomcat、apache、nginx、Weblogic、Jboss等
    线程不回收导致溢出,引发宕机
    数据库连接池不释放导致溢出
    JVM内存参数设置不合理,新生代过大或偏小,永久代设置过小,导致栈溢出
    其它问题

    应用程序类

    程序响应时间超长
    JAVA程序内存溢出,内存中存放大量数据对象
    JAVA程序循环嵌套过多,过于精细的查询条件,子查询间等待超时
    程序中存在死循环引起线程死锁,导致CPU使用率达到100%
    某些返回结果未定义处理方式,导致线程等待,不释放,CPU使用率高

    数据库类

    SGA分配不合理,需要具体情况具体分析
    使用全表扫描
    对于查询业务比较多的表,未建立索引,或建立的索引不合理,在索引列上使用IS NULL和IS NOT NULL
    存在数据库死锁导致数据库连接超时或不释放。
    存在过于复杂的计算,导致CPU、内存和IO使用率较高。
    数据库读写过于频繁,导致IO使用率比较高

    其他问题

    网络问题,被测试环境网络环境小于100M
    客户端问题等等


    性能调优

    调优这块需要大量的知识积累以及多方面的配合。

    性能调优目标与策略

    性能优化的目标不外乎两个:1.时间性能:减小系统执行的时间;2.空间性能:减小系统占用的空间。

    用空间换时间
    各种cache如CPU L1/L2/RAM到硬盘,都是用空间来换时间的策略。这样策略基本上是把计算的过程一步一步的保存或缓存下来,这样就不用每次用的时候都要再计算一遍,比如数据缓冲,CDN,等。这样的策略还表现为冗余数据,比如数据镜象,负载均衡什么的。

    用时间换空间
    有时候,少量的空间可能性能会更好,比如网络传输,如果有一些压缩数据的算法,这样的算法其实很耗时,但是因为瓶颈在网络传输,所以用时间来换空间反而能省时间。

    简化代码
    最高效的程序就是不执行任何代码的程序,所以,代码越少性能就越高。如:减少循环的层数,减少递归,在循环中少声明变量,少做分配和释放内存的操作,尽量把循环体内的表达式抽到循环外,条件表达的中的多个条件判断的次序,尽量在程序启动时把一些东西准备好,注意函数调用的开销(栈上开销),注意面向对象语言中临时对象的开销,小心使用异常,等等。

    调优的基本步骤

    找出主要的瓶颈,首先解决最容易的,再重复测试。
    一次修改一个瓶颈,不要对不需要的地方进行调优.

    配置项性能调优参考

    下面的推荐调优配置都是基于下面的机器配置
    Alt text

    Linux系统调优

    Linux limit 配置修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    修改limit 配置文件,提高linux 本身最大限制,都是在文件最后添加,如果有则是修改
    vi /etc/security/limits.conf
    * soft nproc 102400000
    * hard nproc 102400000
    * soft nofile 1048576
    * hard nofile 1048576

    vi /etc/security/limits.d/90-nproc.conf
    * soft nproc 102400000
    * hard nproc 102400000
    * soft nofile 1048576
    * hard nofile 1048576

    重启生效
    service sshd restart

    为每个普通用户修改limit 限制(经过尝试,两台虚拟机最大的):
    vi /etc/profile
    ulimit -u 102400000
    ulimit -n 1048576
    ulimit -d unlimited
    ulimit -m unlimited
    ulimit -s unlimited
    ulimit -t unlimited
    ulimit -v unlimited
    ulimit -c unlimited

    TCP linux 内核参数设置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    修改配置文件  /etc/sysctl.conf
    vi /etc/sysctl.conf
    # Controls the use of TCP syncookies
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_fin_timeout = 5

    net.ipv4.tcp_keepalive_time = 1200
    net.ipv4.ip_local_port_range = 10000 65000
    net.ipv4.tcp_max_syn_backlog = 262144
    net.core.netdev_max_backlog = 262144
    net.ipv4.tcp_max_tw_buckets = 5000

    生效(执行会报错,需要执行中间两个命令)
    /sbin/sysctl -p
    modprobe bridge
    lsmod|grep bridge
    /sbin/sysctl –p

    JVM 调优

    推荐参数:

    1
    JAVA_ARGS=" -J-Djava.util.logging.manager=com.caucho.log.LogManagerImpl   -J-Dfile.encoding=UTF-8 -J-d64 -J-server -J-Djava.awt.headless=true  -Xms2500m -Xmx2500m -Xmn1100m -XX:PermSize=250m -XX:MaxPermSize=250m -Xss2m  -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection  -XX:CMSMaxAbortablePrecleanTime=5000 -XX:CMSInitiatingOccupancyFraction=85  -XX:+DisableExplicitGC  -XX:+CMSClassUnloadingEnabled  -J-Xloggc:/var/log/gc_product.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution  -Djava.net.preferIPv4Stack=true -XX:+UseCompressedOops -XX:+UseCMSInitiatingOccupancyOnly -XX:MaxTenuringThreshold=8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp "

    Alt text

    Nginx 调优

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    worker_processes 8;
    nginx进程数,建议按照cpu数目来指定,一般为它的倍数, 2倍左右比较合适。

    worker_cpu_affinity 00000001 00000010 00000100 00001000 00000001 00000010 00000100 00001000;
    为每个进程分配cpu,上例中将8个进程分配到4个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

    worker_rlimit_nofile 102400;
    这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n的值保持一致。

    use epoll;
    使用epoll的I/O模型, epoll 是 linux 内核对AIO的实现。

    worker_connections 102400;
    每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes*worker_connections。

    keepalive_timeout 60;
    keepalive超时时间。

    client_header_buffer_size 4k;
    客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。

    open_file_cache max=102400 inactive=20s;
    这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。

    open_file_cache_valid 30s;
    这个是指多长时间检查一次缓存的有效信息。

    open_file_cache_min_uses 1;
    open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。

    MySQLInnoDB调优

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #如果将back_log设定到比你操作系统限制更高的值,将会没有效果, 
    #对应 Linux tcp 内核参数中的net.core.netdev_max_backlog
    back_log = 30000

    # MySQL 服务所允许的同时会话数的上限
    max_connections = 3000

    # 每个客户端连接最大的错误允许数量
    max_connect_errors = 30

    # 所有线程所打开表的数量
    table_cache = 4096

    # 允许外部文件级别的锁. 打开文件锁会对性能造成负面影响
    #external-locking

    # 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小
    max_allowed_packet = 32M

    # 在一个事务中binlog为了记录SQL状态所持有的cache大小
    binlog_cache_size = 4M

    # 独立的内存表所允许的最大容量.
    max_heap_table_size = 128M

    # 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
    sort_buffer_size = 16M

    # 此缓冲被使用来优化全联合(full JOINs 不带索引的联合).
    join_buffer_size = 16M

    # 我们在cache中保留多少线程用于重用
    thread_cache_size = 16

    # 此值只对于支持 thread_concurrency() 函数的系统有意义( 例如Sun Solaris) # 推荐 [CPU数量]*(2~4) 来作为thread_concurrency的值
    thread_concurrency = 8

    # 查询缓冲常被用来缓冲 SELECT 的结果并且在下一次同样查询的时候不再执行直接返回结果
    query_cache_size = 128M

    # 此设置用来保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖.
    query_cache_limit = 4M

    # 被全文检索索引的最小的字长.
    ft_min_word_len = 8

    # 线程使用的堆大小. 此容量的内存在每次连接时被预留.
    thread_stack = 512K

    基础指标

    响应时间

    后端核心服务响应时间不超过100ms
    后端一般服务响应时间不超过300ms
    前端用户页面加载时间不超过3s

    这里是指平均响应时间。但性能测试报告必须给出最大、最小、平均、方差等数值。

    事务成功率

    一般为:99.7%~99.9% ,千分之一到千分之三,根据业务类型来。
    交易型的事务在万分之一。

    负载机的资源利用率

    cpu%<50%
    内存<80%
    network<30%,高了容易丢包
    disk的忙闲<50%
    disk的空间<90%,高了会碎片整理

    应用服务器硬件性能指标

    TotalCPU%<75%
    sysCPU%<30%
    load average<5
    wio%<40%
    network%<30%
    mem%<80%~90%
    disk%busy<60%
    disk queueing <5
    disk usage<90%


    性能监控

    JVM监控工具

    jvisualvm

    java自带的工具,在jdk的bin目录下,使用方法:
    1.到jdk的bin目录下,新建文件jstatd.all.policy
    2.编辑文件:

    1
    2
    3
     grant codebase "file:$JAVA_HOME/lib/tools.jar" {
    permission java.security.AllPermission;

    };

    3.启动:jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.43.22
    4.打开jvisualvm,连接remote

    jinfo

    观察运行中的java程序的运行环境参数:参数包括Java System属性和JVM命令行参数
    实例:jinfo 2083
    其中2083就是java进程id号,可以用jps得到这个id号

    jstack

    可以观察到jvm中当前所有线程的运行情况和线程当前状态
    例: jstack 2083

    jmap

    观察运行中的jvm物理内存的占用情况。
    参数如下:
    -heap:打印jvm heap的情况
    -histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小。
    -histo:live :同上,但是只答应存活对象的情况
    -permstat:打印permanent generation heap情况

    命令使用:
    jmap -heap 2083
    可以观察到New Generation(Eden Space,From Space,To Space),
    tenured generation,Perm Generation的内存使用情况
    生成 dump 文件:
    jmap -dump:format=b,file=heap.bin 16113

    jprofile

    jprofile使用,安装教程

    linux命令监控

    top :查看进程活动状态以及一些系统状况
    vmstat : 查看系统状态、硬件和系统信息等
    iostat : 查看CPU 负载,硬盘状况
    sar : 综合工具,查看系统状况
    mpstat : 查看多处理器状况
    netstat : 查看网络状况
    iptraf : 实时网络状况监测
    tcpdump : 抓取网络数据包,详细分析
    tcptrace : 数据包分析工具
    netperf : 网络带宽工具
    dstat : 综合工具,综合了 vmstat, iostat, ifstat, netstat :等多个信息

    nmon

    nmon使用

    文件句柄数查看及修改

    ulimit –a:查看所有限制值
    ulimit –n:单个进程能够打开的最大文件句柄数量
    lsof -n | awk ‘{print $2}’ | sort | uniq -c | sort –nr:查看进程打开的句柄数,其中第一列是打开的文件句柄数量,第二列是进程号
    lsof –n | grep process_name:查看某进程打开了哪些句柄
    lsof +d ./:查看当前目录下各文件被什么进程占用
    ulimit -SHn 65535:即时修改限制数,重启失效
    永久修改办法:
    1、修改文件:/etc/security/limits.conf,添加:

    • soft nofile 32768 #限制单个进程最大文件句柄数(到达此限制时系统报警)
    • hard nofile 65536 #限制单个进程最大文件句柄数(到达此限制时系统报错)
      2、修改文件:/etc/sysctl.conf,在文件中添加:
      fs.file-max=655350 #限制整个系统最大文件句柄数
      3、修改完成后,执行如下命令:
      sbin/sysctl -p
      使配置生效

    数据库分析与诊断工具

    oracle

    oracle的可以直接看awr和addm报告就行了


    前端性能测试

    基本上使用yslow或者firebug自带的网络监控工具即可。
    自动化前端性能监控可以通过selenium+showslow+yslow来做。

    线上的可以使用公司自己的前端监控平台:
    焦点检测:http://www.focusmonitor.com/
    Probe:http://192.168.28.137:9500/
    BetterCode:http://192.168.28.137:9100/
    Alt text