1、隐藏 Nginx 版本号
为什么要隐藏 Nginx 版本号:一般来说,软件的漏洞都与版本有关,隐藏版本号是为了防止恶意用户利用软件漏洞进行攻击
http {
#...
#在http标签内加入参数server_tokens off;
server_tokens off; #隐藏版本号
#...
}
2、更改 Nginx 服务的默认用户
为什么要更改 Nginx 服务的默认用户:就像更改 ssh 的默认 22 端口一样,增加安全性,Nginx 服务的默认用户是 nobody ,我们更改为 nginx。
1)添加 nginx 用户
useradd -s /sbin/nologin -M nginx
2)更改 Nginx 配置文件
user nginx.nginx; # 指定Nginx服务的用户和用户组
3) 重新加载 Nginx
/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -s reload
4) 验证是否生效
ps aux | grep nginx
3、优化 Nginx worker 进程数
worker 进程数应该设置为等于 CPU 的核数,高流量并发场合也可以考虑将进程数提高至 CPU 核数 * 2。设置成auto,nginx会自动检查设置成cpu的核心;
worker_processes auto;
查看cpu核心的个数:
cat /proc/cpuinfo |grep process
4、绑定 Nginx 进程到不同的 CPU 上
为什么要绑定 Nginx 进程到不同的 CPU 上 :默认情况下,Nginx 的多个进程有可能跑在某一个 CPU 或 CPU 的某一核上,导致 Nginx 进程使用硬件的资源不均,因此绑定 Nginx 进程到不同的 CPU 上是为了充分利用硬件的多 CPU 多核资源的目的。
worker_processes 2; # 2核CPU的配置 worker_cpu_affinity 01 10; worker_processes 4; # 4核CPU的配置 worker_cpu_affinity 0001 0010 0100 1000; worker_processes 8; # 8核CPU的配置 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 1000000;
5、优化 Nginx 处理事件模型
Nginx 的连接处理机制在不同的操作系统会采用不同的 I/O 模型,要根据不同的系统选择不同的事件处理模型,可供选择的事件处理模型有:kqueue 、rtsig 、epoll 、/dev/poll 、select 、poll ,其中 select 和 epoll 都是标准的工作模型,kqueue 和 epoll 是高效的工作模型,不同的是 epoll 用在 Linux 平台上,而 kqueue 用在 BSD 系统中。
(1) 在 Linux 下,Nginx 使用 epoll 的 I/O 多路复用模型
(2) 在 Freebsd 下,Nginx 使用 kqueue 的 I/O 多路复用模型
(3) 在 Solaris 下,Nginx 使用 /dev/poll 方式的 I/O 多路复用模型
(4) 在 Windows 下,Nginx 使用 icop 的 I/O 多路复用模型
events {
use epoll;
}
6、优化 Nginx 单个进程允许的最大连接数
(1) 控制 Nginx 单个进程允许的最大连接数的参数为 worker_connections ,这个参数要根据服务器性能和内存使用量来调整
(2) 进程的最大连接数受 Linux 系统进程的最大打开文件数限制,只有执行了 "ulimit -HSn 65535" 之后,worker_connections 才能生效
(3) 连接数包括代理服务器的连接、客户端的连接等,Nginx 总并发连接数 = worker 数量 * worker_connections, 总数保持在3w左右
events { use epoll; worker_connections 15000; #单个进程允许的最大连接数 }
7、优化 Nginx worker 进程最大打开文件数
worker_rlimit_nofile 65535; # worker 进程最大打开文件数,可设置为优化后的 ulimit -HSn 的结果
9、优化服务器域名的散列表大小
如果在 server_name 中配置了一个很长的域名,那么重载 Nginx 时会报错,因此需要使用 server_names_hash_max_size 来解决域名过长的问题,该参数的作用是设置存放域名的最大散列表的存储的大小,根据 CPU 的一级缓存大小来设置。
server_names_hash_bucket_size 512; # 配置在 http 区块,默认是 512kb ,一般设置为 cpu 一级缓存的 4-5 倍,一级缓存大小可以用 lscpu 命令查看 server { #... server_name www.abcdefghijklmnopqrst.com; # 配置一个很长的域名 #... }
10、开启高效文件传输模式
(1) sendfile 参数用于开启文件的高效传输模式,该参数实际上是激活了 sendfile() 功能,sendfile() 是作用于两个文件描述符之间的数据拷贝函数,这个拷贝操作是在内核之中的,被称为 "零拷贝" ,sendfile() 比 read 和 write 函数要高效得多,因为 read 和 write 函数要把数据拷贝到应用层再进行操作
(2) tcp_nopush 参数用于激活 Linux 上的 TCP_CORK socket 选项,此选项仅仅当开启 sendfile 时才生效,tcp_nopush 参数可以允许把 http response header 和文件的开始部分放在一个文件里发布,以减少网络报文段的数量
http {
#...
sendfile on; # 开启文件的高效传输模式
tcp_nopush on; # 激活 TCP_CORK socket 选择
tcp_nodelay on; #数据在传输的过程中不进缓存
#...
}
11、优化 Nginx 连接超时时间
(1) keepalive_timeout
:该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接
(2) client_header_timeout
:该参数用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 "Request time out (408)" 错误
(3) client_body_timeout
:该参数用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 "Request time out (408)" 错误
(4) send_timeout
:用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接
(5) tcp_nodelay
:默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长
http { #该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接 keepalive_timeout 65; #默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长 tcp_nodelay on; #该参数用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 "Request time out (408)" 错误 client_header_timeout 15; #该参数用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 "Request time out (408)" 错误 client_body_timeout 15; #用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接 send_timeout 25; }