【Day13】Nginx实战训练营
51、Nginx优化-内核参数调整
作为高性能WEB服务器,只调整 Nginx 本身的参数是不行的,因为Nginx服务依赖于高性能的操作系统。
以下为常见的几个 Linux 内核参数优化方法。
-
1、net.ipv4.tcp_max_tw_buckets
对于 tcp 连接,服务端和客户端通信完后状态变为 timewait,假如某台服务器非常忙,连接数特别多的话,那么这个 timewait 数量就会越来越大。毕竟它也是会占用一定的资源,所以应该有一个最大值,当超过这个值,系统就会删除最早的连接,这样始终保持在一个数量级。
这个数值就是由 net.ipv4.tcp_max_tw_buckets 这个参数来决定的。
CentOS7 系统,你可以使用 sysctl -a |grep tw_buckets 来查看它的值,默认为 32768,你可以适当把它调低,比如调整到 8000,毕竟这个状态的连接太多也是会消耗资源的。
但你不要把它调到几十、几百这样,因为这种状态的tcp连接也是有用的,如果同样的客户端再次和服务端通信,就不用再次建立新的连接了,用这个旧的通道,省时省力。
-
2、net.ipv4.tcp_tw_recycle = 1
该参数的作用是快速回收 timewait 状态的连接。上面虽然提到系统会自动删除掉 timewait 状态的连接,但如果把这样的连接重新利用起来岂不是更好。所以该参数设置为1就可以让 timewait 状态的连接快速回收,它需要和下面的参数配合一起使用。
-
3、net.ipv4.tcp_tw_reuse = 1
该参数设置为1,将 timewait 状态的连接重新用于新的 TCP 连接,要结合上面的参数一起使用。 -
4、net.ipv4.tcp_syncookies = 1
tcp 三次握手中,客户端向服务端发起 syn 请求,服务端收到后,也会向客户端发起 syn 请求同时连带 ack 确认,假如客户端发送请求后直接断开和服务端的连接,不接收服务端发起的这个请求,服务端会重试多次,这个重试的过程会持续一段时间(通常高于30s),当这种状态的连接数量非常大时,服务器会消耗很大的资源,从而造成瘫痪,正常的连接进不来,这种恶意的半连接行为其实叫做 syn flood 攻击。设置为1,是开启 SYN Cookies,开启后可以避免发生上述的 syn flood 攻击。
开启该参数后,服务端接收客户端的ack后,再向客户端发送 ack+syn之 前会要求 client 在短时间内回应一个序号,如果客户端不能提供序号或者提供的序号不对则认为该客户端不合法,于是不会发 ack+syn 给客户端,更涉及不到重试。
-
5、net.ipv4.tcp_max_syn_backlog
该参数定义系统能接受的最大半连接状态的 tcp 连接数。客户端向服务端发送了syn包,服务端收到后,会记录一下,该参数决定最多能记录几个这样的连接。在CentOS7,默认是 256,当有syn flood攻击时,这个数值太小则很容易导致服务器瘫痪,实际上此时服务器并没有消耗太多资源(cpu、内存等),所以可以适当调大它,比如调整到 30000。
-
6、net.ipv4.tcp_syn_retries
该参数适用于客户端,它定义发起 syn 的最大重试次数,默认为6,建议改为2。 -
7、net.ipv4.tcp_synack_retries
该参数适用于服务端,它定义发起 syn+ack 的最大重试次数,默认为 5,建议改为 2,可以适当预防 syn flood 攻击。 -
8、net.ipv4.ip_local_port_range
该参数定义端口范围,系统默认保留端口为 1024 及以下,以上部分为自定义端口。这个参数适用于客户端,当客户端和服务端建立连接时,比如说访问服务端的 80 端口,客户端随机开启了一个端口和服务端发起连接,这个参数定义随机端口的范围。
默认为32768 61000,建议调整为1025 61000。 -
9、net.ipv4.tcp_fin_timeout
tcp连接的状态中,客户端上有一个是FIN-WAIT-2状态,它是状态变迁为timewait前一个状态。该参数定义不属于任何进程的该连接状态的超时时间,默认值为60,建议调整为6。
-
10、net.ipv4.tcp_keepalive_time
tcp 连接状态里,有一个是 established 状态,只有在这个状态下,客户端和服务端才能通信。正常情况下,当通信完毕,客户端或服务端会告诉对方要关闭连接,此时状态就会变为 timewait,如果客户端没有告诉服务端,并且服务端也没有告诉客户端关闭的话(例如,客户端那边断网了),此时需要该参数来判定。
比如客户端已经断网了,但服务端上本次连接的状态依然是 established,服务端为了确认客户端是否断网,就需要每隔一段时间去发一个探测包去确认一下看看对方是否在线。这个时间就由该参数决定。
它的默认值为7200秒,建议设置为30秒。
-
11、net.ipv4.tcp_keepalive_intvl
该参数和上面的参数是一起的,服务端在规定时间内发起了探测,查看客户端是否在线,如果客户端并没有确认,此时服务端还不能认定为对方不在线,而是要尝试多次。该参数定义重新发送探测的时间,即第一次发现对方有问题后,过多久再次发起探测。
默认值为75秒,可以改为3秒。 -
12、net.ipv4.tcp_keepalive_probes
第10 和第 11 个参数规定了何时发起探测和探测失败后再过多久再发起探测,但并没有定义一共探测几次才算结束。
该参数定义发起探测的包的数量。
默认为 9,建议设置 2。 -
设置和范例
在Linux下调整内核参数,可以直接编辑配置文件 /etc/sysctl.conf,然后执行 sysctl -p 命令生效
结合以上分析的各内核参数,范例如下
net.ipv4.tcp_fin_timeout = 6
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_max_tw_buckets = 8000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.ip_local_port_range = 1025 61000
net.ipv4.tcp_keepalive_intvl = 3
net.ipv4.tcp_keepalive_probes = 2
资料: https://coding.net/u/aminglinux/p/nginx/git/blob/master/optimize/linux_kernel.md
52、监控 Nginx
-
系统级别监控
top
ps
netstat
ss
lsof -c
tcpdump -nn -i(网卡) 抓包工具
日志 -
配置Nginx状态信息
增加编译参数 –with-http_stub_status_module
配置文件中增加 stub_status on; -
配置Nginx状态
Nginx 有内置一个状态页,需要在编译的时候指定参数 --with-http_stub_status_module 参数方可打开。
也就是说,该功能是由 http_stub_status_module 模块提供,默认没有加载。 -
Nginx配置文件示例
server{
listen 80;
server_name www.1.com;
location /status/ {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.194.0/24;
deny all;
}
}
-
配置说明
location /status/这样当访问 /status/ 时即可访问到状态页内容。
stub_status on 即打开了状态页。
access_log off 不记录日志
allow 和 deny 只允许指定 IP 和 IP 段访问,因为这个页面需要保护起来,并不公开,当然也可以做用户认证。 -
测试和结果说明
测试命令: curl -x127.0.0.1:80 www.1.com/status/ -
结果如下:
Active connections: 1
server accepts handled requests
11 11 11
Reading: 0 Writing: 1 Waiting: 0
说明:
active connections – 活跃的连接数量
server accepts handled requests — 总共处理的连接数、成功创建的握手次数、总共处理的请求次数
需要注意,一个连接可以有多次请求。
reading — 读取客户端的连接数
writing — 响应数据到客户端的数量
waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接,数值过大,nginx 可能有问题。
资料:
https://coding.net/u/aminglinux/p/nginx/git/blob/master/mon/stat.md
53 Nginx架构-LNMP
php-fpm 以单独的一个服务存在
Nginx 直接处理静态文件
Nginx 会把 php 的请求通过代理的方式交给 php-fpm
-
LNMP架构搭建
安装 MySQL/Mariadb
安装 php-fpm
安装 Nginx
参考: http://www.apelearn.com/study_v2/chapter18.html -
配置Nginx和php
配置如下(在server部分添加):
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/tmp/php-fcgi.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
配置说明:
1、fastcgi_params 文件在 /usr/local/nginx/conf/ 下面,其内容为 fastcgi 相关的变量
2、fastcgi_pass 后面跟的是 php-fpm 服务监听地址,可以是 IP:PORT,也可以是 unix socket 地址,也支持 upstream 的地址
3、fastcgi_index 定义索引页,如果在 server 内其他部分有定义 index 参数,该配置可以忽略
4、fastcgi_param 这行其实可以在 fastcgi_params 文件里面定义 SCRIPT_FILENAME 变量,这个变量如果不定义,php 的请求是没办法访问的。
资料:
https://coding.net/u/aminglinux/p/nginx/git/blob/master/lnmp/nginx_php.md