【NGINX入门】16.使用JMeter压力测试工具测试NGINX限流配置实践

1. 摘要

本文介绍WINDOWS环境下,使用压力测试工具JMeter实现对网站的NGINX限流配置后,进行压力测试的方法和实践过程。

2. 操作内容

2.1 JMeter安装

jmeter下载的地址是:
http://jmeter.apache.org/download_jmeter.cgi ,例如选择了5.2的版本
https://mirrors.bfsu.edu.cn/apache//jmeter/binaries/apache-jmeter-5.2.zip
现在到本地,然后解压到特定目录。
例如: C:\Program Files\apache-jmeter-5.2

2.2 JMeter界面设置为中文

找到jmeter下的bin目录,打开jmeter.properties 文件
第37行修改为 language=zh_CN
去掉前面的#,以后打开就是中文界面了

2.3 JMeter环境配置

新增环境变量JMETER_HOME,填好路径(C:\Program Files\apache-jmeter-5.2)之后,点击确定,具体如附图所示:

编辑CLASSPATH变量,在CLASPATH加上 %JMETER_HOME%\lib\ext\ApacheJMeter_core.jar;%JMETER_HOME%\lib\jorphan.jar;%JMETER_HOME%\lib\logkit-2.0.jar,然后点击确定,再次点击确定,此时路径已经添加完成。如附图所示

2.4 JMeter并发测试配合

(1)配置线程组

运行apache-jmeter-5.2\bin下的jmeter.bat文件。
添加线程组,编辑线程数,这里设置6个线程数,循环2次,就是一台机器发送6*2=12个请求。


(2)配置HTTP请求

点击线程组,右击添加→取样器→HTTP请求;
添加HTTP请求,这里以访问公司官网为例,输入网址。

(3)配置查看结果

点击HTTP请求,右击添加→监听器→查看结果树,聚合报告;

(4)启动进程

点击线程组,右击启动,可以选择任意一台电脑来运行。

Thread Group说明:

  • Name:任意,具有有意义的名字
    Comments:备注信息

  • Action to be taken after a Sampler error
    a.Contiune:继续。某一个请求遇到错误后,其他请求继续执行。我们在大量用户并发的时候,某个请求失败属正常现象
    b.Start Next Thread Loop:如遇到错误后面的请求将不再执行,等下一轮再开始执行。例如线程组中包含登录和发帖2个请求,若登录请求失败,发帖请求将不再执行,等下一次重新迭代,从登录开始执行。
    c.Stop Thread:遇到错误就停止线程再也不执行了。例如线程组中有50个线程,其中某一个线程的某个请求遇到错误即停止线程不再执行,剩下49个线程继续执行。若线程错误的比较多,剩余的线程就较少,此时负载数量就不足了,测试结果不满足测试要求,因此一般不会勾选此项。
    d.Stop Test:某个线程某个请求遇到错误,停止所有线程,也就是停止整个测试,但是线程中的余下的请求还是会执行完再停止。例如线程1中包含登录和发帖2个请求,其他线程遇到错误,现在要全部停下来,线程1发帖请求还是会执行,然后再停止测试。
    e.Stop Test Now:遇到错误立即停止所有线程,即整个测试。

  • Thread Properties
    a.Number of Threads(users) :线程数,一个线程相当于一个虚拟用户
    b.Ramp-Up Period(in second):线程启动开始运行的时间间隔,单位秒。即所有线程在多长时间内全部启动。例如线程60个,Ramp-Up Period设置为20s,那么每秒启动60/20=3个线程,不填写默认设置为0,即所有线程在开启场景后立即启动。
    c.Loop Count:循环次数。勾选forever,将一直执行,除非手动停止或崩溃
    d.Delay Thread creation until needed:延时创建线程直到该线程需要采样时。
    勾选,例如50个线程Ramp-Up Period为10s,那么每隔1s启动50/10=5个线程并运行下面的请求(状态为running);不勾选,测试计划开始后启动所有线程(状态为new),但是不立即执行下面的请求。例如50个线程Ramp-Up Period为10s,那么计划开始后所有线程全部就绪,但第一秒只有5个线程开始运行请求。实际应用中选择哪种都可以,不影响测试结果。
    个人理解:例如银行办业务10个人,勾选,柜台只有一个人在办理(running状态),剩下的人可以坐在位置上等候;不勾选,10个人都站在柜台外面排队等候(不是坐着),等待叫号。

  • Scheduler:调度器
    a.Duration(seconds):持续时间,测试计划持续多长时间。
    b.Startup delay(seconds):启动延时。点击启动按钮后,仅初始化场景,不运行线程,等待延时时间到才运行。

然后就可以查看各种结果了。点击清除扫帚可以清除本次结果。

2.5 限流测试

(1)限制访问速率

NGINX配置如下,表示上述规则限制了每个IP访问的速度为2r/s。

http {
 #配置artarva官网的限流参数
 limit_req_zone $binary_remote_addr zone=artarva_limit:10m rate=2r/s;
...

server { 
       ...   
       limit_req zone=artarva_limit;
    }
}

然后让1秒钟内发起7个请求,持续1次,看下效果。

可以知道,成功了2次,失败了5次。Nginx的限流统计是基于毫秒的,我们设置的速度是2r/s,转换一下就是500ms内单个IP只允许通过1个请求,从501ms开始才允许通过第二个请求。

(2)BURST缓存处理

我们看到,我们短时间内发送了大量请求,Nginx按照毫秒级精度统计,超出限制的请求直接拒绝。这在实际场景中未免过于苛刻,真实网络环境中请求到来不是匀速的,很可能有请求“突发”的情况,也就是“一股子一股子”的。Nginx考虑到了这种情况,可以通过burst关键字开启对突发请求的缓存处理,而不是直接拒绝。
来看我们的配置:

http {
 #配置artarva官网的限流参数
 limit_req_zone $binary_remote_addr zone=artarva_limit:10m rate=2r/s;
...

server { 
       ...   
       limit_req zone=artarva_limit burst=4;
    }
}

我们加入了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。如果单个IP在1s内发送7个请求,结果会怎样呢?

相比实例一成功数增加了4个,这个我们设置的burst数目是一致的。具体处理流程是:1个请求被立即处理,4个请求被放到burst队列里,另外一个请求被拒绝。通过burst参数,我们使得Nginx限流具备了缓存处理突发流量的能力。

但是请注意:burst的作用是让多余的请求可以先放到队列里,慢慢处理。如果不加nodelay参数,队列里的请求不会立即处理,而是按照rate设置的速度,以毫秒级精确的速度慢慢处理。

(3)nodelay降低排队时间

实例二中我们看到,通过设置burst参数,我们可以允许Nginx缓存处理一定程度的突发,多余的请求可以先放到队列里,慢慢处理,这起到了平滑流量的作用。但是如果队列设置的比较大,请求排队的时间就会比较长,用户角度看来就是RT变长了,这对用户很不友好。有什么解决办法呢?nodelay参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理,请注意,这意味着burst设置了nodelay时,系统瞬间的QPS可能会超过rate设置的阈值。nodelay参数要跟burst一起使用才有作用。
延续实例二的配置,我们加入nodelay选项:

http {
 #配置artarva官网的限流参数
 limit_req_zone $binary_remote_addr zone=artarva_limit:10m rate=2r/s;
...

server { 
       ...   
        limit_req zone=artarva_limit burst=4 nodelay;
    }
}

单个IP 1s内并发发送7个请求,结果如下,成功反馈6个,失败了1个。

跟实例二相比,请求成功率没变化,但是总体耗时变短了。这怎么解释呢?实例二中,有4个请求被放到burst队列当中,工作进程每隔500ms(rate=2r/s)取一个请求进行处理,最后一个请求要排队2s才会被处理;实例三中,请求放入队列跟实例二是一样的,但不同的是,队列中的请求同时具有了被处理的资格,所以实例三中的5个请求可以说是同时开始被处理的,花费时间自然变短了。

但是请注意,虽然设置burst和nodelay能够降低突发请求的处理时间,但是长期来看并不会提高吞吐量的上限,长期吞吐量的上限是由rate决定的,因为nodelay只能保证burst的请求被立即处理,但Nginx会限制队列元素释放的速度,就像是限制了令牌桶中令牌产生的速度。

看到这里你可能会问,加入了nodelay参数之后的限速算法,到底算是哪一个“桶”,是漏桶算法还是令牌桶算法?当然还算是漏桶算法。考虑一种情况,令牌桶算法的token为耗尽时会怎么做呢?由于它有一个请求队列,所以会把接下来的请求缓存下来,缓存多少受限于队列大小。但此时缓存这些请求还有意义吗?如果server已经过载,缓存队列越来越长,RT越来越高,即使过了很久请求被处理了,对用户来说也没什么价值了。所以当token不够用时,最明智的做法就是直接拒绝用户的请求,这就成了漏桶算法。

(4)网站实用配置

结合目前服务器的性能,访问网页的数据大小,针对该官网,辉哥增加了NGINX的一个实用配置,如下:

http {
 #配置artarva官网的限流参数
 limit_req_zone $binary_remote_addr zone=artarva_limit:10m rate=30r/s;
...

server { 
       ...   
           #流量配置限速,突发设置为4;
          limit_req zone=artarva_limit burst=4 nodelay;
          # 限制传输速度(如果有N个并发连接,则是 N * limit_rate)
          limit_rate 30k;
    }
}

Jmeter采用每秒访问31次,持续1000次循环。看看访问成功率情况。
每秒失败1次,负荷限流预期

此时,查看该台服务器的负载情况,已经达到CPU负荷的极限了。一般建议CPU使用率不要超过85%为宜。

3. 参考

(1)apache jmeter下载与安装https://jingyan.baidu.com/article/acf728fd68e7bef8e510a3cb.html

(2)jmeter如何并发测试 https://jingyan.baidu.com/article/624e74599860da75e8ba5abb.html

(3)【NGINX入门】11.Nginx限流算法及配置实践
https://www.jianshu.com/p/93e2790a6817

(4)性能测试网站
http://www.fairytest.com/newversion/apiTool

(12)12 个免费在线的 Web 网站性能测试工 -模拟全球用户 50并发具]https://www.oschina.net/news/21033/12-free-online-tools-for-website-testing

你可能感兴趣的:(【NGINX入门】16.使用JMeter压力测试工具测试NGINX限流配置实践)