1、着手在测试前:理清数据流向,数据流程分解
  通过绘制数据流向图,以便清晰的列出所有可能出现瓶颈的位置,避免在分析过程中遗漏可能的瓶颈点。
  系统架构分解——水池模型
  要查找瓶颈,首先要对系统的架构有详细的了解,清楚知道所有可能成为瓶颈的位置。只有这样才能在遇到问题是合理的设计测试用例,对流程的各个步骤进行逐一排查。
  举个例子,家里厨房的水池下水堵了,我们要找原因,首先得知道水池的下水道都有哪些部分:

  简单的看,可以把下水道分解为水漏、上连接管、回水弯、下连接管后接入地漏。再查找堵塞位置时,我们可以将水直接导入回水弯,排除水漏和上连接管道堵塞的可能。
  应用在测试中,我们也可以利用直接向应用中间件发请求,来排除Web代理层的瓶颈。
  通过绘制流向图,可以更清晰的展现系统中数据流向,帮助我们在定位瓶颈的过程始终能迅速的分析预计到下一个可能的瓶颈位置。

  如上图,是在play一个Mobile game时的数据流向图。
  2、直观的指征:检索日志中的异常
  日志是系统异常的直接反映,通过客户端(负载工具端)、服务器端的日志,可以迅速确定瓶颈可能存在的方向。一些在大用户量大并发情况下的功能问题,也会在错误日志中体现。
  在性能测试过程中,一般情况是不把全部日志打开的,而是尽量保持与生产环境的设置相同,生产环境开启什么样的日志级别,在性能测试环境中也应该开启同样的级别。
  但是往往在生产环境出于性能考虑,并不会把日志级别开的非常高,所以在发现系统存在性能问题时,我们可以适当调高日志级别,以便获得更多的信息。
  在日志中,我们可以由一些关键字直接推断出系统的问题所在,比如:
  · Too many open files
  Linux下存在句柄数限制,系统的默认值较小,在测试前应该优化,另外还要怀疑是否程序存在打开句柄却在某些情况下没有关闭。
  · OutOfMemoryError/Cannot allocate memory
  Java环境的虚拟内存异常,往往需要关注是否有溢出。
  · SQLException
  数据库语句执行异常,一般日志中还会有数据库返回的信息。
  · Connection closed/connection refused
  连接被关闭被拒绝,一般是连接数限制不能承担当前的压力。
  3、底层的反映:分析硬件资源占用
  硬件资源也是系统性能达到瓶颈点的重要指征,如果没有在日志中找到异常,那么通过监控硬件资源消耗,往往可以发现系统的资源瓶颈。
  3.1 CPU占用率
  CPU的高占用,并不一定表示有问题,因为实现优性能的一方面是充分发挥当前的硬件资源能力。

  但是如上图这样CPU长期出于满负荷,很值得我们关注,至少说明在大多数情况下,系统已经是在耗用大的计算能力进行计算,运算能力已经成为瓶颈。
  另外还要注意CPU是消耗在User还是Sys还是Wait, 如果是Wait,还要观察其他硬件资源,查看CPU是在等待什么。
  3.2 内存占用
  内存在性能测试中是被重点关注的指标,因为它是反映重大缺陷——内存泄露的直接指标,但是我们应该注意到,在JAVA框架中的内存泄漏是发生在虚拟内存中的。
  观察内存/虚拟内存的占用情况,尤其是在压力消失后的内存占用恢复情况,是比较直接的判断内存泄漏的依据。

  如果观察到如上图的内存使用情况,在每次Full GC后,占用的内存都没能恢复到原来的水平,如果在压力撤除一段时间后,内存依旧不能恢复,那么十有八九当前系统存在内存泄漏。
  3.3 磁盘I/O
  通常情况下,磁盘是计算机中速度慢的一个子系统,因此很多情况中,磁盘I/O会成为系统的瓶颈。实际上在设计高性能系统的时候,会把避免磁盘I/O作为一个首要准则。
  虽然当前的技术发展让存储系统的读写速度不断提升,但高昂的成本使得大多数情况下,高速存储会使用在数据库或文件服务器上,而不会使用在应用服务器中。所以在我们进行性能测试时,要更多的注意应用服务器的磁盘使用情况。