zoukankan      html  css  js  c++  java
  • 性能测试:压力机性能瓶颈分析及优化

    性能测试过程中,为了给服务器足够的压力,少不了要使用压力机,即模拟客户端的机器,压力机如果使用不当,测试结果就会不准确,反映不了服务器的真实性能情况。
    因此,我们需要充分了解压力机,并对其进行调优,从而避免压力机自身瓶颈对压测带来影响,为性能测试结果的准确可靠,提供前置条件。
    下面,我们分三步来确保压力机靠谱:
    STEP1:了解压力机自身可能成为瓶颈的配置,并调优;
    STEP2:了解被模拟程序自身可能成为瓶颈的配置,并调优;
    STEP3:找到压力机上,单进程的性能瓶颈,以避免在施压过程中受此干扰;

    STEP1

    1,网络通讯协议相关配置调优(以TCP为例),优化最大连接数,理论上TCP最大连接数为65535,因此,理论上单机的瞬时并发最大不可能超过65535;

    既然存在使用压力机,必然是通过某种网络通讯协议来建立连接,并发送请求。以TCP协议为例,先来了解TCP协议:
    如何标识一个TCP连接?
    在确定最大连接数之前,先来看看系统如何标识一个tcp连接。系统用一个4四元组来唯一标识一个TCP连接:{local ip, local port,remote ip,remote port}。
    client最大tcp连接数(理论上)
    client每次发起tcp连接请求时,除非绑定端口,通常会让系统选取一个空闲的本地端口(local port),该端口是独占的,不能和其他tcp连接共享。tcp端口的数据类型是unsigned short,因此本地端口个数最大只有65536,端口0有特殊含义,不能使用,这样可用端口最多只有65535,所以在全部作为client端的情况下,最大tcp连接数为65535,这些连接可以连到不同的server ip。
    server最大tcp连接数(理论上),与本文无关,详见:http://www.cnblogs.com/mydomain/archive/2013/05/27/3100835.html
    上面给出的是理论上的单机最大连接数,在实际环境中,受到机器资源、操作系统等的限制,其最大并发tcp连接数远不能达到理论上限,另外1024以下的端口通常为保留端口。
    除端口限制外,TCP连接的内存设置,也会影响到最大连接数。在默认2.6内核配置下,经过试验,每个socket占用内存在15~20k之间。
    综上,关于TCP最大连接数,linux/Unix下有以下三类配置可以调优
    A:Linux网络内核对本地端口号范围的限制:
    修改/etc/sysctl.conf文件,在文件中添加或修改如下行:

    ```
    net.ipv4.ip_local_port_range = 1024 65000
    ```
    
    这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。

    修改完成后,执行sysctl
    sysctl -p
    如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个
    B:Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数的限制,如果没有防火墙,可忽略此条:(参考:http://blog.chinaunix.net/uid-24907956-id-3428052.html)
    首先确定有没有防火墙
    service iptables status
    如果有,条件允许,可以直接
    service iptables stop iptables
    再查看防火墙状态:
    service iptables status
    运行结果:
    iptables: Firewall is not running.
    如果不能关闭防火墙,则修改IP_TABLE防火墙对最大跟踪的TCP连接数:
    修改/etc/sysctl.conf文件,在文件中添加或修改如net.ipv4.ip_conntrack_max = 40960
    修改完成后,执行sysctl
    sysctl -p
    如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。若按上述参数进行设置,则理论上单独一个进程最多可以同时建立40960个TCP客户端连接。
    C:TCP相关内存限制
    在默认2.6内核配置下,经过试验,每个socket占用内存在15~20k之间。
    修改配置文件:/etc/sysctl.conf

    net.core.rmem_default = 262144
    net.core.wmem_default = 262144
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    **net.ipv4.tcp_rmem = 4096 4096 16777216
    net.ipv4.tcp_wmem = 4096 4096 16777216
    net.ipv4.tcp_mem = 786432 2097152 3145728
    net.ipv4.tcp_max_syn_backlog = 262144**
    net.core.netdev_max_backlog = 20000
    net.ipv4.tcp_fin_timeout = 15
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_max_orphans = 131072

    配置文件生效:sudo /sbin/sysctl -p
    主要看这几项,按机器内存大小,进行调节:
    net.ipv4.tcp_rmem 用来配置读缓冲的大小,三个值,第一个是这个读缓冲的最小值,第三个是最大值,中间的是默认值。我们可以在程序中修改读缓冲的大小,但是不能超过最小与最大。为了使每个socket所使用的内存数最小,我这里设置默认值为4096。
    net.ipv4.tcp_wmem 用来配置写缓冲的大小。读缓冲与写缓冲在大小,直接影响到socket在内核中内存的占用。
    net.ipv4.tcp_mem 则是配置tcp的内存大小,其单位是页,而不是字节。当超过第二个值时,TCP进入 pressure模式,此时TCP尝试稳定其内存的使用,当小于第一个值时,就退出pressure模式。当内存占用超过第三个值时,TCP就拒绝分配 socket了,查看dmesg,会打出很多的日志“TCP: too many of orphaned sockets”。
    net.ipv4.tcp_max_orphans 这个值也要设置一下,这个值表示系统所能处理不属于任何进程的 socket数量,当我们需要快速建立大量连接时,就需要关注下这个值了。当不属于任何进程的socket的数量大于这个值时,dmesg就会看 到”too many of orphaned sockets”。

    另外,附上LINUX 查看tcp连接数及状态,以及状态详请,参见: http://blog.sina.com.cn/s/blog_623630d50101r93l.html

    2,调整最大打开文件数;http://www.cnblogs.com/peida/archive/2013/02/26/2932972.html
    在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。
    lsof打开的文件可以是:
    普通文件、目录、网络文件系统的文件、字符或设备文件、(函数)共享库、管道,命名管道、符号链接、网络文件(例如:NFS file、网络socket,unix域名socket)、还有其它类型的文件,等等
    故,作为压力机,每个TCP/UDP连接都会占用一个文件打开数,此处,可能成为瓶颈。

    3,打开进程数限制(root用户本项是无限)

    如果你对进程总数量没有特殊要求,可以不修改本选项。
    执行命令:
    ulimit -a
    查看结果:
    max user processes (-u) 16484
    如果此项可能成为瓶颈,则修改此项。

    4,确认网卡、路由不会成为瓶颈
    此处不做详解。

    5,确认网络带宽

    此处不做详解,查看实时带宽流量 https://help.aliyun.com/knowledge_detail/5988901.html?pos=11

    6,压力机其他可调优的参数:

    参考:http://blog.csdn.net/my_yang/article/details/45788717


    STEP2     以java为例

    1,java堆内存、栈内存,理论详见:http://blog.csdn.net/qh_java/article/details/9084091
    重要的是:
    在java中每new一个线程,jvm都是向操作系统请求new一个本地线程,此时操作系统会使用剩余的内存空间来为线程分配内存,而不是使用jvm的内存。这样,当操作系统的可用内存越少,则jvm可用创建的新线程也就越少。见:http://blog.sina.com.cn/s/blog_684fe8af0100wzg5.html
    因此,可以理解为线程使用的内存,不在“使用-Xms -Xmx设置的内存”中,需要根据实际情况进行调节,不宜过大,否则能启动的线程数量越小;
    如果是maven项目,使用jemeter,且使用maven的jemeter插件,那么在POM里,jmeter插件中设置此内存大小;

    另外,附上如何计算,只考虑内存的情况下,机器理论上能打开的最大线程数:http://blog.csdn.net/feng27156/article/details/19333575
    官网查线程栈默认值(64位为1M)http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html 搜XX:ThreadStackSize

    2,maven内存

    maven本身编译的内存也不宜设置过小或过大,会影响能启动的线程数;

    3,其他施压程序的瓶颈

    有的框架或程序,可以限制单台机器,连接到本服务的最大线程数,此配置可能成为瓶颈,比如dubbo的 actives配置(每服务消费者每服务每方法最大并发调用数)
    其他类似的配置;

    STEP3:

    找到压力机上,施压程序单进程的性能瓶颈;
    如果是物理机,且并发数不大(几百到4/5千),可以忽略此条。
    除以上已知配置可能会影响压力机性能瓶颈以外,不排除其他影响压力机性能的因素,因此,在远程机器上,搭建一个mock程序,该程序什么都不做,直接返回成功。注意:mock程序部署机器物理配置最好能和压力机对等(对等时,至少部署两台),如果不能对等,部署多台,以排除部署机器的瓶颈;
    通过逐步增加线程数,观察平均响应时间和TPS,随着线程数的增加,TPS很难上升,平均响应时间明显增加的情况下,基本可以说明已经达到压力机的瓶颈,记下此时的线程数,在压测时,单台压力机最大线程数不宜超过该线程数,否则压测结果中,TPS和平均响应时间不准,压测结果不准确。

    总结:
    STEP3很重要,因为在实践中,一台8核 64G内存的机器,单进程,最大的线程数超过10000时,被测服务(20台机器做实验)的压力很难再上去,因此STEP1只能说是排除那些可能成为瓶颈的机器配置,STEP2为避免踩已知的坑,STEP3才能确认压力机的单进程施压能力到底是多少;

    原文地址http://blog.csdn.net/kaka1121/article/details/51496387

    ==============================================================================================================================================================================================================================================

    性能测试中TPS上不去的几种原因浅析

    昨晚在某个测试群看到有人问了一个问题:压力测试中TPS一直上不去,是什么原因?稍微整理了下思路,列举性的简略回答了他的问题。

    这篇博客,就具体说说在实际压力测试中,为什么有时候TPS上不去的原因。如有遗漏或不对的,请评论区指出,不胜感激。。。

    先来解释下什么叫TPS:

    TPS(Transaction Per Second):每秒事务数,指服务器在单位时间内(秒)可以处理的事务数量,一般以request/second为单位。

    关于性能测试的其他一些常见术语,可参考之前的博客:性能测试:常见术语浅析

    下面就说说压测中为什么TPS上不去的原因:

    1、网络带宽

    在压力测试中,有时候要模拟大量的用户请求,如果单位时间内传递的数据包过大,超过了带宽的传输能力,那么就会造成网络资源竞争,间接导致服务端接收到的请求数达不到服务端的处理能力上限。

    2、连接池

    可用的连接数太少,造成请求等待。连接池一般分为服务器连接池(比如Tomcat)和数据库连接池(或者理解为最大允许连接数也行)。

    (关于连接池的具体内容,可参考之前的博客:性能测试:连接池和线程

    3、垃圾回收机制

    从常见的应用服务器来说,比如Tomcat,因为java的的堆栈内存是动态分配,具体的回收机制是基于算法,如果新生代的Eden和Survivor区频繁的进行Minor GC,老年代的full GC也回收较频繁,那么对TPS

    也是有一定影响的,因为垃圾回收其本身就会占用一定的资源。

    4、数据库配置

    高并发情况下,如果请求数据需要写入数据库,且需要写入多个表的时候,如果数据库的最大连接数不够,或者写入数据的SQL没有索引没有绑定变量,抑或没有主从分离、读写分离等,

    就会导致数据库事务处理过慢,影响到TPS。

    5、通信连接机制

    串行、并行、长连接、管道连接等,不同的连接情况,也间接的会对TPS造成影响。

    (关于协议的连接,可参考之前的博客:HTTP协议进阶:连接管理

    6、硬件资源

    包括CPU(配置、使用率等)、内存(占用率等)、磁盘(I/O、页交换等)。

    7、压力机

    比如jmeter,单机负载能力有限,如果需要模拟的用户请求数超过其负载极限,也会间接影响TPS(这个时候就需要进行分布式压测来解决其单机负载的问题)。

    8、压测脚本

    还是以jemter举个例子,之前工作中同事遇到的,进行阶梯式加压测试,最大的模拟请求数超过了设置的线程数,导致线程不足。

    提到这个原因,想表达意思是:有时候测试脚本参数配置等原因,也会影响测试结果。

    9、业务逻辑

    业务解耦度较低,较为复杂,整个事务处理线被拉长导致的问题。

    10、系统架构

    比如是否有缓存服务,缓存服务器配置,缓存命中率、缓存穿透以及缓存过期等,都会影响到测试结果。

    PS:性能瓶颈分析不能单从局部分析,要综合起来,多维度分析问题原因。上面列出的几点,可能有描述不当或者遗漏的,仅供参考。。。

    如果有不准确的,请评论指正,谢谢!

  • 相关阅读:
    在线api文档
    Android Studio 快捷键
    AtomicBoolean运用
    ubuntu下Pycharm安装及配置
    Pycharm Professional Edition 激活码(license)
    opengl中对glOrtho()函数的理解
    附加作业
    个人最终总结
    mysql
    创建数据库
  • 原文地址:https://www.cnblogs.com/111testing/p/11218538.html
Copyright © 2011-2022 走看看