nginx调优






尽管NGINX比其他Web服务器要年轻得多,但它已Swift成为一种流行的选择。 其成功的部分原因在于,它是寻求轻量级高性能Web服务器的人们的首选Web服务器。

在今天的文章中,我们将采用现成的NGINX实例并对其进行调整,以从已经高性能的Web服务器中获得更多收益。 尽管不是完整的调优指南,但本文应为读者提供对调优基础知识和一些常见的NGINX调优参数的扎实了解。

但是,在进行调优之前,让我们先安装NGINX。

安装NGINX

对于本文,我们将在基于Ubuntu Linux的服务器上运行NGINX,因此我们可以使用apt-get命令执行安装。

root@nginx-test:~# apt-get install nginx

此步骤将安装NGINX的常规安装,该安装已开箱即用地设置了一些调整参数。 但是,NGINX的默认安装没有提供太多的内容提供方式。 为了给自己一个现实的Web应用程序进行调整,让我们继续并从GitHub部署示例站点。

root@nginx-test:~# git clone https://github.com/BlackrockDigital/startbootstrap-clean-blog.git /var/www/html
Cloning into '/var/www/html'...
remote: Counting objects: 308, done.
remote: Total 308 (delta 0), reused 0 (delta 0), pack-reused 308
Receiving objects: 100% (308/308), 1.98 MiB | 0 bytes/s, done.
Resolving deltas: 100% (119/119), done.
Checking connectivity... done.

在进行性能调整时,重要的是要了解要调整的应用程序的类型。 对于NGINX,了解您要调整下游应用程序提供的静态内容还是动态内容非常重要。 这两种类型的内容之间的差异可以更改要更改的调整参数以及这些参数的值。

在本文中,我们将调整NGINX以提供静态HTML内容。 虽然大多数参数通常都适用于NGINX,但并非所有参数都适用。 最好将本文用作您自己的调整和测试的指南。

现在,我们已经安装了基本实例并部署了示例站点,让我们看看NGINX的即用型安装性能如何。

建立基准

性能调整的第一步之一就是建立度量单位。 对于本文,我们将使用HTTP负载测试工具ApacheBench ,也称为ab来生成到我们的NGINX系统的测试流量。

这个负载测试工具非常简单,对于Web应用程序非常有用。 ApacheBench为不同类型的负载测试方案提供了很多选项。 但是,对于本文,我们将使测试非常简单。

我们将使用-c (并发级别)和-n (请求数)参数集来执行ab命令。

$ ab -c 40 -n 50000 http://159.203.93.149/

当执行ab ,我们会将并发级别( -c )设置为40 ,这意味着ab将与目标NGINX实例保持至少40并发HTTP会话。 我们还将通过-n参数设置对请求数量的限制。 从本质上讲,这两个选项将共同导致ab打开40并发HTTP会话并发送尽可能多的请求,直到达到50000请求为止。

让我们继续进行测试运行以建立基线,并确定我们今天将用于测试的指标。

# ab -c 40 -n 50000 http://159.203.93.149/
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 159.203.93.149 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        nginx/1.10.0
Server Hostname:        159.203.93.149
Server Port:            80

Document Path:          /
Document Length:        8089 bytes

Concurrency Level:      40
Time taken for tests:   16.904 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      420250000 bytes
HTML transferred:       404450000 bytes
Requests per second:    2957.93 [#/sec] (mean)
Time per request:       13.523 [ms] (mean)
Time per request:       0.338 [ms] (mean, across all concurrent requests)
Transfer rate:          24278.70 [Kbytes/sec] received

在上面的输出中,有几个有趣的指标。 今天,我们将重点关注“ Requests per second指标。 该指标显示了我们的NGINX实例在一秒钟内可以处理的平均请求数。 在调整参数时,我们应该看到该指标上升或下降。

Requests per second:    2957.93 [#/sec] (mean)

从上面可以看出,每秒的平均请求数是2957.93 。 这似乎很多,但是随着我们的继续,我们会将这个数字增加很多。

性能调整时,重要的是要记住进行一些小的增量更改,并将结果与基准进行比较。 对于本文, 2957.93请求是我们的基准度量。 为了使参数成功,它必须导致每秒的请求增加。

设置好基准指标后,让我们开始调整NGINX。

工作线程

NGINX中最基本的调优参数之一是可用的工作线程数。 默认情况下,此参数的值为auto ,它告诉NGINX为系统可用的每个CPU创建一个工作线程。

对于大多数系统,每个CPU一个工作进程可以平衡性能并减少开销。 但是,在本文中,我们试图最大程度地利用NGINX提供的静态内容,而这应该是非常低的CPU开销。 让我们继续前进,看看通过增加该值每秒可以收到多少个请求。

对于我们的第一个测试,让我们继续,为系统上的每个CPU启动两个工作进程。

为了弄清楚我们需要多少个工作进程,我们首先需要知道该系统有多少个CPU。 尽管有很多方法可以执行此操作,但在本示例中,我们将使用lshw命令显示硬件信息。

root@nginx-test:~# lshw -short -class cpu
H/W path      Device  Class      Description
============================================
/0/401                processor  Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GHz
/0/402                processor  Intel(R) Xeon(R) CPU E5-2650L v3 @ 1.80GH

从上面的输出中,我们的系统似乎是2 CPU系统。 这意味着对于我们的第一个测试,我们将需要设置NGINX以启动总共4工作进程。

我们可以通过编辑/etc/nginx/nginx.conf文件中的worker_processes参数来/etc/nginx/nginx.conf 。 这是默认的NGINX配置文件,也是我们今天要调整的所有参数的位置。

worker_processes auto;

上面显示了此参数设置为auto的默认值。 让我们继续将其更改为4的值。

worker_processes 4;

设置新值并保存/etc/nginx/nginx.conf文件后,我们将需要重新启动NGINX才能使配置更改生效。

root@nginx-test:~# service nginx restart
root@nginx-test:~# ps -elf | grep nginx
1 S root     23465     1  0  80   0 - 31264 sigsus 20:16 ?        00:00:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
5 S www-data 23466 23465  0  80   0 - 31354 ep_pol 20:16 ?        00:00:00 nginx: worker process
5 S www-data 23467 23465  0  80   0 - 31354 ep_pol 20:16 ?        00:00:00 nginx: worker process
5 S www-data 23468 23465  0  80   0 - 31354 ep_pol 20:16 ?        00:00:00 nginx: worker process
5 S www-data 23469 23465  0  80   0 - 31354 ep_pol 20:16 ?        00:00:00 nginx: worker process
0 S root     23471 23289  0  80   0 -  3628 pipe_w 20:16 pts/0    00:00:00 grep --color=auto nginx
root@nginx-test:~#

从上面我们可以看到,现在有4正在运行的进程,名称为nginx: worker process 。 这表明我们的更改是成功的。

检查效果

开始我们的其他工作人员后,让我们再次运行ab来查看吞吐量是否有任何变化。

# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"
Requests per second:    3051.40 [#/sec] (mean)

看来我们的更改影响很小:我们原来的Requests per second2957.93 ,新值是3051.40 。 此处的差异大约是每秒多100个请求。 虽然这是一种改进,但这不是我们一直在寻找的改进水平。

worker_processes 8;

让我们继续,将worker_processes值更改为8 ,这是可用CPU数量的四倍。 为了使此更改生效,我们将再次需要重新启动NGINX服务。

root@nginx-test:~# service nginx restart

服务重新启动后,我们可以继续并重新运行ab测试。

# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"
Requests per second:    5204.32 [#/sec] (mean)

似乎8工作线程比4工作线程具有更大的作用。 与基准指标相比,我们可以看到,通过8工作线程,我们每秒能够处理大约2250以上的请求。

总体而言,这似乎比我们的基准有了重大改进。 问题是,如果进一步增加工作线程的数量,我们会看到多少改进?

请记住,最好进行小的增量更改并衡量性能提高的每一步。 对于此参数,我只需将其值增加为2的倍数,然后每次都重新运行测试即可。 我将重复此过程,直到每秒请求数不再增加。 但是,对于本文,我们将继续进行下一个参数,将worker_processes值设置为8

工人连接

我们要调整的下一个参数是worker_connections中的worker_connections配置。 此值定义每个工作程序的最大TCP会话数。 通过增加此值,希望是我们可以增加每个工人流程的能力。

可以在/etc/nginx/nginx.conf配置文件的events块中找到worker_connections设置。

events {
        worker_connections 768;
        # multi_accept on;
}

Ubuntu安装NGINX的默认设置是768 。 对于第一个测试,我们将尝试将此设置更改为1024并测量该更改的影响。

events {
        worker_connections 1024;
        # multi_accept on;
}

像之前的配置更改一样,为了使此调整生效,我们必须重新启动NGINX服务。

root@nginx-test:~# service nginx restart

在重新启动NGINX之后,我们可以使用ab命令运行另一个测试。

# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"
Requests per second:    6068.41 [#/sec] (mean)

再次,我们的参数更改导致性能显着提高。 只需对worker_connections进行很小的更改,我们就可以每秒增加800请求的吞吐量。

进一步增加工作线程

如果worker_connections的微小变化可以每秒增加800请求,那么更大的变化会产生什么影响? 找出这一点的唯一方法是更改参数并再次测试。

让我们继续,将worker_connections值更改为4096

worker_rlimit_nofile 4096;

events {
        worker_connections 4096;
        # multi_accept on;
}

我们可以看到worker_connections值为4096 ,但是还有另一个参数的值为4096worker_rlimit_nofile参数用于定义每个工作进程最大打开文件数。 现在指定此参数的原因是,在调整每个工作程序的连接数时,还必须调整打开文件的限制。

使用NGINX,每个打开的连接至少等于一个或有时两个打开的文件。 通过将最大连接数设置为4096 ,我们实质上定义了每个工作程序最多可以打开4096文件。 如果不将worker_rlimit_nofile设置为至少与worker_connections相同的值,则实际上可能会降低性能,因为每个worker都会尝试打开新文件,并且会受到打开文件限制或1024拒绝。

应用这些设置后,让我们继续进行测试,以查看我们的更改如何影响NGINX。

# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"
Requests per second:    6350.27 [#/sec] (mean)

ab测试运行的结果来看,我们似乎每秒能够添加约300请求。 尽管这可能不像我们之前的每秒800请求那么重要,但仍然可以提高吞吐量。 这样,我们将保留此参数,继续进行下一个项目。

调整工作量

对此进行调优NGINX或其他任何事情时,务必牢记要调优的服务的工作量。 在我们的案例中,NGINX仅提供静态HTML页面。 在提供静态HTML时,有一组调整参数非常有用。

http {

        open_file_cache max=1024 inactive=10s;
        open_file_cache_valid 120s;

/etc/nginx/nginx.conf文件中的open_file_cache参数用于定义NGINX可以保持打开并缓存在内存中的文件的长度和数量。

本质上,这些参数允许NGINX在第一个HTTP请求期间打开我们HTML文件,并使这些文件保持打开状态并缓存在内存中。 在后续的HTTP请求发出时,NGINX可以使用此缓存,而不必重新打开源文件。

在上文中,我们定义了open_file_cache参数,以便NGINX可以缓存max的imum 1024打开文件。 但是,在这些文件中,如果10秒钟之内未访问它们,则缓存将失效。 open_file_cache_valid参数定义一个时间间隔,以检查当前缓存的文件是否仍然有效; 在这种情况下,每120秒一次。

这些参数将大大减少NGINX必须打开和关闭我们的静态HTML文件的次数。 这意味着每个请求的总体工作量较少,这意味着更高的吞吐量。 让我们用另一行ab命令测试我们的理论。

# ab -c 40 -n 50000 http://159.203.93.149/ | grep "per second"
Requests per second:    6949.42 [#/sec] (mean)

每秒增加近600请求, open_file_cache参数会产生很大的影响。 尽管此参数可能非常有用,但请务必记住,此参数在我们的示例中有效,因为我们只是在提供静态HTML。 如果我们正在测试每次都提供动态内容的应用程序,则这些参数可能会导致最终用户出现渲染错误。

摘要

在这一点上,我们采用了现成的NGINX实例,测量了每秒2957.93请求的基准度量,并将该实例调整为6949.42请求。 结果,我们每秒增加了大约4000请求。 为此,我们不仅更改了一些关键参数,还尝试了这些参数。

尽管本文仅涉及了几个关键的NGINX参数,但本文中用于更改和衡量影响的方法可以与其他常见的NGINX调整参数一起使用,例如启用内容缓存gzip压缩 。 有关更多调优参数,请查看《 NGINX管理指南》 ,其中包含有关管理NGINX以及针对各种工作负载进行配置的大量信息。

翻译自: https://www.javacodegeeks.com/2016/09/tuning-nginx.html

nginx调优