开发者
资源
Nginx 1.14.2 物理机场景Web server 调优指南(CentOS 7.6)
Nginx 1.14.2 物理机场景Web server 调优指南(CentOS 7.6)
发表于2022/10/19
3040

调优概述

Nginx介绍

Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,其特点是占有内存少,并发能力强,支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能,并且支持很多第三方的模块扩展。

Nginx性能调优从大的方面来说,在系统设计之初,需要考虑硬件的选择,操作系统的选择,基础软件的选择;从小的方面来说,包括每个子系统的设计,算法选择,如何使用编译器的选项,如何发挥硬件最大的性能等等。

调优原则

在性能优化时,我们必须遵循一定的原则,否则,有可能得不到正确的调优结果。主要有以下几个方面:

  • 对性能进行分析时,要多方面分析系统的资源瓶颈所在,因为系统某一方面性能低,也许并不是它自己造成的,而是其他方面造成的。如CPU利用率是100%时,很可能是内存容量太小,因为CPU忙于处理内存调度。

  • 一次只对影响性能的某方面的一个参数进行调整,多个参数同时调整的话,很难界定性能的影响是由哪个参数造成的。

  • 由于在进行系统性能分析时,性能分析工具本身会占用一定的系统资源,如CPU资源、内存资源等等。我们必须注意到这点,即分析工具本身运行可能会导致系统某方面的资源瓶颈情况更加严重。

调优思路

性能调优首要要发现问题,找到性能瓶颈点,然后根据瓶颈所处层级选择优化的方法,下图介绍了Nginx物理机的调优思路。

图1 Nginx物理机调优思路

1.jpg

调优分析思路如下:

  1. 对于服务端的问题,需要重点定位的硬件指标包括CPU、内存、硬盘、BIOS配置,其中CPU是需要重点关注的:服务端虚拟机CPU未压满或存在明显热点函数直接影响最终测试结果,需要注意的是虚拟机的CPU是否压满是在虚拟机内部查看,不是在host主机上查看;需要重点关注的软件指标包括应用软件、OS层的优化,该部分的调优对于性能的提升是很可观的。

  2. 对于网络问题,需要重点定位的包括网络带宽和网络中断,处理网络中断的核是否压满是需要重点关注的,http长连接场景需要重点关注网络带宽是否达到瓶颈。

  3. 对于客户端问题:客户端的性能是否满足测试需要,尤其对于http短连接场景。

硬件调优

配置BIOS

目的

对于不同的硬件设备,通过在BIOS中设置一些高级选项,可以有效提升服务器性能。

  • 服务器上的SMMU一般用来完成设备的地址转换,并且可以实现设备隔离,在虚拟化中很实用,但是在物理机测试场景下,SMMU可能会导致性能下降,尤其对于小包网络场景,因此建议关闭该功能提升服务器性能。在虚拟机场景需要打开此配置来使用PCI直通功能。

  • 在本测试场景中,预取会导致cache污染,cache miss增加,因此建议关闭预取功能。

方法

步骤 1 关闭SMMU。

   方法一:

               1.         重启服务器,按Esc键进入BIOS设置界面。

               2.         依次进入“Advanced > MISC Config >  > Support Smmu”。

               3.         将“Support Smmu”设置为“Disabled”,按“F10”保存退出(永久有效)。

   方法二:

               1.         执行vim /etc/grub2-efi.cfg命令。

               2.         搜索字段"4.14",在内核代码中加入"iommu.passthrough=1"。

2.png

3.         保存退出后,重启服务器。

 步骤 2      关闭预取

               1.         进入BIOS设置界面。

               2.         依次进入“Advanced > MISC Config > CPU Prefetch”。

               3.         将“CPU Prefetch”设置为“Disabled”,按“F10”保存退出(永久有效)。

操作系统调优

配置扩展文件描述符

目的

在Nginx环境中,需要配置最大打开文件数为102400,否则在测试过程中可能会导致软件最大打开文件数被限制在1024,影响服务器性能。

方法

步骤 1      在"/etc/security/limits.conf"文件中写入以下配置。

*   soft     nofile      102400 
               *   hard     nofile      102400

      其中:*表示所有用户;hard表示严格的设定,必定不能超过这个设定的数值;soft表示警告的设定,可以超过这个设定值,但是若超过则有警告信息。

步骤 2      保存文件并重启服务器。

配置内核参数

目的

对于不同的操作系统,通过调优内核参数,可以有效的提高服务器的性能。

方法

步骤 1      执行vim /etc/sysctl.conf命令,并输入下列内核参数:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.ip_local_port_range = 1024    65500
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 262144
net.core.netdev_max_backlog = 262144
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

内核参数说明如下表所示:

linux参数

参数定义

当前值

默认值

net.ipv4.tcp_tw_reuse

1表示允许将TIME-WAIT sockets重新用于新的TCP连接,0表示关闭。

1

0

net.ipv4.tcp_keepalive_time

TCP发送keepalive探测消息的间隔时间(秒),用于确认TCP连接是否有效

60

7200

net.ipv4.tcp_fin_timeout

socket 保持在 FIN_WAIT_2 状态的最大时间

1

60

net.ipv4.tcp_max_tw_buckets

减少TIME_WAIT连接数,避免过多TIME_WAIT连接占用网络资源导致新建连接资源紧张,时延增加

5000

262144

net.ipv4.ip_local_port_range

增加可用端口范围,避免大量连接占用端口时,新建连接不断寻找可用端口导致的性能跳水

1024 65500

32768 61000

net.core.somaxconn

定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数

65535

128

net.ipv4.tcp_max_syn_backlog

表示SYN队列的长度,加大队列长度可以容纳更多等待连接的网络连接

262144

1024

net.core.netdev_max_backlog

当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目

262144

1000

net.core.rmem_max

系统套接字读最大缓冲区

16777216

131071

net.core.wmem_max

系统套接字写最大缓冲区,增加buffer大小,避免大量新建连接导致buffer溢出,出现无法建立连接情况

16777216

131071

net.nf_conntrack_max

最大跟踪连接数

0

65536

说明

当使用容器时,由于不能关闭nf_conntrack模块,所以需要在内核参数中增加nf_conntrack相关设置,防止table记录满产生丢包问题。

在/etc/sysctl.conf文件中还需添加如下内核参数:

net.netfilter.nf_conntrack_max=0
net.nf_conntrack_max=0

步骤 2      写入参数后保存配置文件

步骤 3      执行命令以生效配置:

/sbin/sysctl -p

关闭nf_conntrack模块

注意

使用容器的场景不能做本章节的操作。

目的

内核的nf_conntrack模块可以用来实现NAT,但是在没有使用NAT的场景,开启nf_conntrack模块会导致不需要的CPU消耗,甚至可能导致table记录满产生丢包问题,因此可以考虑关闭nf_conntrack模块提升性能。

方法

步骤 1      在"/etc/modprobe.d/blacklist.conf"文件中加入如下参数:

install nf_conntrack /bin/false
blacklist nf_conntrack
blacklist nf_conntrack_ipv6
blacklist xt_conntrack
blacklist nf_conntrack_ftp
blacklist xt_state
blacklist iptable_nat
blacklist ipt_REDIRECT
blacklist nf_nat
blacklist nf_conntrack_ipv4

步骤 2      保存文件后,重启服务器使文件生效。

关闭selinux

目的

为了减少selinux的性能损耗,关闭selinux。

方法

步骤 1     执行vim /etc/sysconfig/selinux命令,打开selinux文件。

步骤 2    将"SELINUX=enforcing" 改为 "SELINUX=disabled"。

步骤 3     保存文件,重启服务器。

步骤 4     执行如下语句确认selinux是否关闭,如果SELinux status参数显示为disabled即为关闭状态。

/etc/sysctl.conf/usr/sbin/sestatus -v

配置网卡中断绑核

目的

  1. 每个CPU对应一个网卡,每个CPU内的中断绑核只绑在属于本CPU的网卡上,按node各自绑核。

  2. 中断个数在尽量少的情况下满足当前所有业务core在客户端满压下满CPU运作即可。

方法

步骤 1    关闭irqbalance。

          若要对网卡进行绑核操作,需要关闭irqbalance。

1. 关闭irqbalance服务,重启失效。

systemctl stop irqbalance.service

2. 停止irqbalance服务,永久有效。

systemctl disable irqbalance.service

3. 查看irqbalance服务状态是否已关闭。

systemctl status irqbalance.service

步骤 2   网卡中断绑核。

        网卡中断绑核,绑定的核专门用于处理网卡中断。

        1. 设置队列深度为CPU的核数

ethtool -L $eth1 combined $cnt

        2. 查询中断号。

cat /proc/interrupts | grep $eth1 | awk -F ':' '{print $1}'

        3. 根据中断号,将每个中断各绑定在一个核上。

echo $cpunum > /proc/irq/$irq/smp_affinity_list

绑核脚本示例

绑核脚本内容如下所示,以4core的http短连接场景的绑核脚本为例,如果要修改绑核脚本,只需修改要绑定的网口名eth1,以及要绑定的core,然后在关闭irqbalance.service的情况下使用脚本即可:

#!/bin/bash
cnt=2
eth1=enp3s0
ethtool -L $eth1 combined $cnt
irq1=`cat /proc/interrupts| grep -E ${eth1} | head -1 | awk -F ':' '{print $1}'`
irq1=`echo $irq1`i=0
while(( $i < 1))
do
for cpunum in 2 3
do
echo $cpunum "->" $irq1
echo  $cpunum > /proc/irq/$irq1/smp_affinity_list
let "irq1++"
done
let "i++"
done
    
参数说明如下表所示:

参数名称

参数解释

cnt

网口队列数

eth1

通信中使用的网口名

irq1

网口eth1对应的中断号

cpumun

分配给网口eth1用于处理网卡中断的核

Nginx调优

目的

通过调优Nginx的配置文件,可以有效的提高服务器的性能。

方法

步骤 1    Nginx.conf根据测试的业务核数,修改worker_processes和worker_cpu_affinity配置。

             调优原则:以压满业务核为前提,用尽量少的中断核,配合中断脚本使用。             

步骤 2    为nginx示例配置html文件。

            Html文件策略:每个nginx实例分别访问独自的html文件。

            故每起一个nginx实例,就需要增加一个html文件。在2p测试时,需要在/Nginx/html下新增一个html,并在相应的nginx.conf中修改所有location中的对应页面。            

步骤 3    Nginx启动添加taskset。

taskset -c N /nginx/sbin/nginx -c /nginx/conf/nginx.conf

            将Nginx的master进程绑定在N号core上。

            绑定策略:跟自己的业务core绑在同一个node或者CPU上。

配置文件参数说明

以Nginx虚拟机http短连接为例,主要的配置参数如下,配合绑核中断即可使用。对于其他场景只需修改worker_processes和worker_cpu_affinity即可。

Nginx的配置是区块型的,包括全局配合(如user、worker_processes等)和模块配置(其中events为events模块,http为http模块),每个模块配置中又分为各个区块,如http模块中有server区块,server有location区块。Nginx基本配置与参数说明如下:

  user      root;

  worker_processes 3;

  worker_cpu_affinity

  1

  10

  100;    

  error_log /dev/null; 

  worker_rlimit_nofile 102400;

#全局配置:

#定义Nginx运行的用户和用户组。

#nginx进程数,建议设置为等于CPU总核心数。

#通过worker_cpu_affinity给每个worker进程绑定一个CPU, 1表示启用core0,10表示启用core1,100表示启动core2,依次类推,100000表示启用core5,1后面有n个0就表示启动core n。

#错误日志文件路径,/dev/null表示关闭nginx日志。

#指定一个nginx进程打开的最多文件描述符数目,受系统进程的最大打开文件数量(ulimit -n)限制。

events {

  worker_connections  102400;

   

  multi_accept on;

   

  use epoll; 

  accept_mutex on;

  }

#events模块配置:

#定义每个进程的最大连接数,受系统进程的最大打开文件数量限制,并发总数是worker_processes 和 worker_connections 的乘积。

#告诉nginx进程收到一个新连接通知后接受尽可能多的连接,如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的连接。

#设置工作模式为epoll,除此之外还有select,poll,kqueue,rtsig和/dev/poll模式。

#打开accept_mutex,避免了worker争夺资源造成的上下文切换以及try_lock的锁开销

http {

include       mime.types;

default_type  application/octet-stream;

access_log /dev/null;

sendfile        on;

tcp_nopush     on;

tcp_nodelay     on;

sendfile_max_chunk 512k;

keepalive_timeout  65;

keepalive_requests 2000;

client_header_buffer_size 4k;

large_client_header_buffers 4 32k;

server_names_hash_bucket_size 128;

client_max_body_size 100m;

open_file_cache max=102400 inactive=40s;

open_file_cache_valid 50s;

open_file_cache_min_uses 1;

open_file_cache_errors on;

#http模块配置:

#文件扩展名与文件类型映射表。

#默认文件类型。

#Nginx访问日志路径,/dev/null表示关闭访问日志。

#开启高效文件传输模式,获取文件跨过用户态;.gzip压缩器需要在用户态进行,因此无法和sendfile共存。

#开启防止网络阻塞,返回数据的首个数据包会携带从sendfile中获取大块的数据后才会被发送。

#开启防止网络阻塞。

#限制最大sendfile的文件大小,防止过大的文件占据整个工作进程默认为“无限制”。

#设置客户端连接保存活动的超时时间。

#设置一个keep-alive连接上可以服务的请求的最大数量。当最大请求数量达到时,连接被关闭。

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

#设置客户端请求的Header头缓冲区大小:4为个数,32k为大小,表示申请4个32k。当http 的URI太长或者request   header过大时会报414   Request URI too large或400 bad request错误。

#保存服务器名字的hash表的大小。

#控制全局nginx所有请求报文大小,100M。

#max设置缓存中的最大元素数,在缓存溢出时,删除最近最少使用(LRU)的元素;inactive定义一个时间,如果在此期间未访问该元素,则从该缓存中删除该元素。

#多长时间检查一次缓存的有效信息。也就是说即使我一直访问这个文件,30s后会检查此文件的更改信息是否变化,发现变化就更新

# open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件更改信息一直是在缓存中打开的

#启用文件查找错误的缓存

server {

listen       10000 reuseport;

server_name  localhost;

access_log off;

location / {

root     html;

index    index.html index.htm;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root     html;

}

}

#设定主机配置

#侦听10000端口,http短连接场景建议打开reuseport

#定义使用localhost访问

#关闭主机的访问日志

#默认请求

#定义服务器的默认网站根目录位置,root是web根目录

#定义首页索引文件的名称及顺序

# 定义错误提示页面

# HTTPS server

server {

listen       20000 ssl;

server_name  localhost;

ssl_certificate        /usr/local/nginx/server_2048.crt;

ssl_certificate_key    /usr/local/nginx/server_2048.key;

ssl_session_cache    shared:SSL:1m;

ssl_session_timeout  5m;

ssl_protocols  TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

ssl_ciphers &quot;EECDH+ECDSA+AESGCM   EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384   EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5   !EXP !PSK !SRP !DSS !RC4&quot;;

ssl_prefer_server_ciphers  on;

location / {

root     html;

index    index.html index.htm;

}

}

}

#配置ssl加密

#侦听20000端口

#定义使用localhost访问

# ssl_certificate证书是公钥,它会被发送到连接服务器的每个客户端

# ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到client。

#设置ssl会话缓存的类型和大小,shared:SSL:1m表示我所有的nginx工作进程共享ssl会话缓存,1M可以存放约4000个sessions。

#客户端可以重用会话缓存中ssl参数的过期时间,5分钟

#用于启动特定的加密协议

#选择加密套件

#设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。

#定义服务器的默认网站根目录位置,root是web根目录

#定义首页索引文件的名称及顺序

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞