nginx 优化:
1. cpu: 核心配置
方法 1: worker_processes auto; 自动调用[推荐]
方法 2: worker_processes 4; 手工配置
检查 CPU 核心:yum install numactl
命令: numactl --hardware
[root@leilei ~]# numactl --hardware
available: 1 nodes (0)
node 0 cpus: 0 1
node 0 size: 4095 MB
node 0 free: 194 MB
node distances:
node 0
0: 10
2. cpu 绑定减少进程切换:
# 如 双核 CPU 配置: worker_cpu_affinity 01 10;
四核 cpu 配置: worker_cpu_affinity 0001 0010 0100 1000;
八核 cpu 配置: worker_cpu_affinity 0001 0010 0100 1000 1001 1010 1100 1101;
自动切换: worker_cpu_affinity auto;
3. 进程优先级:
方法1: worker_priority 0; 默认配置
方法2: worker_priority -20; 优先级最高
4. 并发连接:
worker_connections 100000;
nginx 默认为 1024, 当访问量过大时 1024 就不够用了
需要修改 worker_rlimit_nofile 文件打开数, 这个不能被 worker_connections 超出, 否则会出现 wern, 所以基本配置:
worker_rlimit_nofile 65535; # 不应该超过 ulimit - a 中的数值.
worker_connections 100000; # 单个 work 进程的最大并发数
worker_rlimit_nofile 65535;
worker_connections 100000;
5. 事件处理模型:
events {
use epoll;
worker_rlimit_nofile 65535;
worker_connections 100000; # 上下游连接加起来 都是使用这个句柄数.
multi_accept on; # 允许尽可能接受多的连接 默认值 off 建议改为 on
accept_mutex on; # 防止被唤醒, 从而加重服务器压力, 默认值 off 建议改为 on
accept_mutex_delay 10ms; # 设置获得互斥锁的最少延迟时间。默认值 500ms
}
6. 开启同时接受多连接:
events {multi_accept on;
}
7. 避免频繁唤醒:
events {accept_mutex on;
}
8. sendfile 高效传输:
配置区块: http server location
sendfile on;
9. 内核优化:
cat /etc/sysctl.cnf
net.core.netdev_max_backlog = 1000 # 默认值 1000 在高并发情况下该值可以改为 102400
net.core.somaxconn = 128 # 默认值 1000 在高并发情况下可以设置更高 102400
net.ipv4.tcp_max_orphans = 32768 # 默认值 32768 这是 TCP 连接套戒指缓存, 用于防止 DDOS 攻击, 在内存较大时可以修改的大一些 如: 102400
net.ipv4.tcp_max_syn_backlog = 256 # 默认值 256 这是用于记录未被确认的连接, 一般需要加大 如: 102400
net.ipv4.tcp_timestamps = 1 # 默认值 1 这是用于数据包时间戳的支持设置, 避免网络异常, 默认值 1 建议修改为 0 禁用此设置
net.ipv4.tcp_synack_retries = 5 # 默认值 5 这是设置内核放弃 TCP 连接之前向客户端发送 SYN+ACK 包的数量, 用于三次握手, 如果值设置过多会影响性能 建议改为 2
net.ipv4.tcp_syn_retries = 5 # 默认值 5 与上面功能类似, 建议修改为 2
net.ipv4.tcp_retries1 = 3 # 默认值 3 达到路由上线后, 更新路由缓存 表示放弃回应一个 TCP 连接请求前进行重传的次数。
net.ipv4.tcp_retries2 = 15 # 默认值 15 达到上限后关闭 TCP 连接 表示放弃在已经建立通讯状态下的一个 TCP 数据包前进行重传的次数。
10. 多核负载均衡:
listen 80 reuseport;
listen 443 ssl http2 default_server reuseport;
连接请求的速度是很高的,但是请求不需要大量的处理,reuseport 也能大幅提高性能, 此优化项需要继续 centos7 以上或 Linux 内核 3.9 以上的版本才可以使用. 因为它是基于内核层面负载均衡
引用 reuseport 参数后,对引用的socket,accept_mutex 参数将会无效
11. TCP 连接握手优化[内核调优]:
net.ipv4.tcp_syn_retries = 6 # 主动建立连接, 发送 SYN 报文的重试次数.
net.ipv4.ip_local_port_range = 32768 60999 # 建立连接后本地端口的可用范围
net.ipv4.tcp_fastopen = 3 #fast open 配置: 0 关闭 1 作为客户端使用 2 作为服务器使用 3 无论客户端和服务器都可以使用
net.ipv4.tcp_retries1 = 3 # 丢包重传上限, 到达上限, 更新缓存
net.ipv4.tcp_retries2 = 15 # 丢包重传上限, 到达上限, 更新缓存
net.ipv4.ip_local_port_range = 20000 65535 # 可用端口范围
net.ipv4.tcp_sack = 1 # 错误状态快速恢复
#net.ipv4.tcp_fack = 1 #拥塞避免和 快速重传功能 当 tcp_sack 设置为 0 的时候,这个值即使设置为 1 也无效
net.ipv4.tcp_max_syn_backlog = 128 #syn_rcvd 状态连接最大个数# 防止 TCP 半连接报文攻击
net.ipv4.tcp_synack_retries = 1 # 三次握手中的第二次握手, 该配置决定 Linux 内核放弃连接之前发送 syn+ack 确认包的数量
net.ipv4.tcp_tw_recycle = 1 #TCP 连接中的 time_wait sockets 的快速回收
net.ipv4.tcp_tw_reuse = 1 # 开启连接复用, 将 time_wait sockets 重新用于新的 tcp 连接.
net.ipv4.ip_local_port_range = 20000 65535 # 对外处理连接的端口反围
fs.file-max = 204800 # 文件句柄数
#nginx keepalive
net.ipv4.tcp_keepalive_time = 7200 # 发送心跳的周期
net.ipv4.tcp_keepalive_intvl = 75 # 探测包发送重试时间间隔
net.ipv4.tcp_keepalive_probes = 9 # 探测包重试次数
这些调优参数加入到 /etc/sysctl.conf 后 使用 sysctl -p 让他生效
cat >>/etc/sysctl.conf<<EOF
net.ipv4.tcp_syn_retries = 6
net.ipv4.ip_local_port_range = 32768 60999
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
net.ipv4.ip_local_port_range = 20000 65535
net.ipv4.tcp_sack = 1
#net.ipv4.tcp_fack = 1
net.ipv4.tcp_max_syn_backlog = 128
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 20000 65535
fs.file-max = 204800
net.ipv4.tcp_max_tw_buckets = 10000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_orphans = 16384
#nginx keepalive
net.core.somaxconn = 16384
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_fin_timeout = 20
EOF
sysctl -p
12. TCP 连接建立优化:
net.core.netdev_max_backlog = 25000 # 默认 128 [防止 syn 攻击 backlog] 这是接受来自网卡, 但是未被内核协议栈处理的报文队列长度.
net.ipv4.tcp_max_syn_backlog = 25000 # 默认 128 syn_rcvd 状态连接最大个数# 防止 TCP 半连接报文攻击
13. TCP 设置时间戳, 避免复用:
net.ipv4.tcp_timestamps = 0
14. 主动建立连接应用层超时时间[反向代理相关]:
proxy_connect_timeout 60s;
15. 超出处理能力, 对新来的 SYN 直接丢弃连接 [可以无需配置]:
net.ipv4.tcp_abort_on_overflow = 0
16. SYN 队列满后, 新的 SYN 不进入列队 1 代表启用 0 关闭:
net.ipv4.tcp_syncookies = 1
17. 开启自动调整缓存模式:
net.ipv4.tcp_moderate_rcvbuf = 1
18 . 读缓存最小值, 默认值, 最大值 该参数会覆盖 net.core.rmem_max 配置:
net.ipv4.tcp_rmem = 4096 87380 6291456
19. 写缓存最小值, 默认值, 最大值 该参数会覆盖 net.core.wmem_max 配置:
net.ipv4.tcp_wmem = 4096 16384 4194304
20. 系统无内存压力, 启动压力模式阈值, 最大值, 单位为页的数量:
net.ipv4.tcp_mem = 1541646 2055528 3083292
21. 调整接受窗口与应用缓存:
net.ipv4.tcp_adv_win_scale = 1
计算公式: 应用缓存 = buffer / (2^tcp_adv_win_scale)
22. 启用 Nagle 算法:
该算法会将很多小报文组成一个大的报文发出, 减少传输次数, 提高带宽利用率, 但是会发送延迟.
默认开启
可用区域: http server location
开启方法: tcp_nodelay off;
禁用方法: tcp_nodelay on; [推荐.]
23. 避免小报文发送:
默认配置 1460
默认关闭 [推荐]
postpone_output 1460;
开启方法: tcp_nopush on; 仅在 sendfile on; 配置加入的时候这才会生效.
24. 减少 time_wait 时间.[四次握手等待确认时间]:
CLOSE_WAIT 状态:
如果频繁出现 CLOSE_WAIT 说明应用进程没有及时响应对端关闭连接
LAST_ACK 状态:
等待接收主动关闭端操作系统发来的针对 FIN 的 ack 报文.
25. 发送 FIN 报文的重试次数,0 相当于 8:
net.ipv4.tcp_orphan_retries = 0
26. 保持在 FIN_WAIT_2 状态的时间:
net.ipv4.tcp_fin_timeout = 60
27. time_wait 状态连接的最大数量, 超出后关闭连接:
net.ipv4.tcp_max_tw_buckets = 262144
#net.ipv4.tcp_tw_recycle = 0 开启后, 可以同时作为客户端和服务器都能够使用 time-wait 状态端口, 不够安全, 报文延迟, 重复等. 不建议开启.
28. 延迟关闭 TCP 连接 lingering_close 指令:
lingering_close off|on|always
lingering_close off 关闭此功能
lingering_close on 启用此功能
lingering_close always 无条件启用此功能
29. 延迟关闭 TCP 连接 lingering_time 指令:
语法: lingering_time time;
默认: lingering_time 30s;
可用区块: http server location
启用后, 最长读取用户请求时间为设置的 30s 超出后立刻关闭连接.
30. 检测客户端是否有请求到达, 超时后关闭连接:
语法: lingering_timeout time;
默认: lingering_timeout 5s;
可用区块: http server location
启用后, 检测客户端是否仍有请求到达, 超时后没有数据到达则关闭连接.
31. 以 rst 代替正常四次握手关闭连接:
语法: reset_timedout_connection on|off;
默认: reset_tomedout_connection off;
可用区块: http server location
32.TLS/SSL 优化握手性能:
语法: ssl_session_cache off|none|[builtin[:size]]
默认: ssl_session_cache none|off|buitin|shared:name:size;
可用区块: http server
off: 不适用 session 缓存, 并且 nginx 在协议中告诉客户端 session 缓存不被使用.
none: 不适用 session 缓存
buitin: 使用 openssl 的 session 缓存, 由于在内存中, 所以只有当同一个客户端两次命中到 worker 进程时,session 缓存才会生效.
shared:name:size : 定义一个共享内存, 为所有 woker 进程提供 session 缓存服务,1MB 大约可以用于 4000 个 session.
33. http 长连接优化:
语法: keepalive_requests number
默认: keepalive_requests 100;
可用区块: http,server,location,upstream
http 长连接优点: 减少握手次数, 通过减少并发连接从而减少了服务器资源消耗, 降低 TCP 拥塞控制的影响.
34. gzip 压缩:
语法: gzip on|off
默认: gzip off;
可用区块: http server location if in location
例子:
gzip on; # 开启压缩
gzip_min_length 500; # 小于多少字节不压缩
gzip_buffers 4 256k; # 开辟一块缓冲区进行连续压缩响应
gzip_http_version 1.1; # 只对 http1.1 进行压缩
gzip_comp_level 5; # 压缩的级别 [1-9]
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; # 需要压缩的类型
gzip_vary on; # 开启后响应客户端压缩.. 响应头会增加 Vary: Accept-Encoding
gzip_proxied expired no-cache no-store private auth; # 是否对上游进行压缩
gzip_disable "MSIE [1-6]\."; # 不进行压缩
35. 磁盘 i / o 优化:
1. sedfile 零拷贝
2. 内存磁盘
减少写入:
1. aio
2. 增大 error_log 急别
3. 关闭 access_log
4. 压缩 access_log
5. 是否启用 proxy buffering
6. syslog 代替本地 io
线程池优化 thread poll
35.1 大文件较多, 启用 directIO 功能避免 buffered io 模式下磁盘页缓存的拷贝消耗:
直接I/O:
directio size|off;
默认: directio off;
作用区块: http server location
例子:
server {directio 10M;
}
异步I/O:
directio_alignment size|off;
默认: directio_alignment 512;
作用区块: http server location
server {directio_alignment 10M;
}
35.2 aio 使用场景:
需要添加模块 --with-threads:
例子:
1. 配置文件顶部添加线程池:
thread_pool leilei threads=32 max_queue=65536;
2. 对应模块中调用线程池
aio threads=leilei;
网上博文有介绍到这个模块, 声称可以达到 9 倍性能提升.
35.3 减少磁盘 i /o:
官方模块: empty_gif 只能应用于 location, 默认在 nginx 中.
empty_gif
36.1 日志优化:
1. 配置日志压缩:
server {access_log logs/leilei.log main buffer=32k gzip=2 flush=5s;
}
2. 重启 nginx
3. 通过 zcat 查看日志.
36.2 日志传递给 syslog [高吞吐量下该配置有利于性能提升]:
rsyslog 配置: vim /etc/rsyslog.conf
1.
$ModLoad imudp # 取消注释
$UDPServerRun 514 # 取消注释
2.
local6.* /var/log/nginx/nginx.log
3. nginx 配置文件添加:
access_log syslog:server=127.0.0.1:514,facility=local6,nohostname,tag=nginx,serverity=info main;
4. 重启 rsyslog
systemctl restart rsyslog.service
37. 隐藏 nginx 版本:
http {server_tokens off;
}
正文完