Nginx优化大全

1:版本号隐藏

# 优化原因:一般来说,软件的漏洞都与版本有关,隐藏版本号是为了防止恶意用户利用软件漏洞进行攻击

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    server_tokens       off;     # 此配置改为off即可
    keepalive_timeout   65;
    types_hash_max_size 4096;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

# 修改前
[root@virtual_host ~]# curl 127.0.0.1 -I
HTTP/1.1 200 OK
Server: nginx/1.20.1

# 修改后
[root@virtual_host ~]# curl 127.0.0.1 -I
HTTP/1.1 200 OK
Server: nginx

2:隐藏 Nginx 版本号和软件名

# 优化原因:软件的漏洞都与版本有关,隐藏版本号是为了防止恶意用户利用软件漏洞进行攻击,而软件名可以进行修改,否则黑客知道是 Nginx 服务器更容易进行攻击,需要注意的是,隐藏 Nginx 软件名需要重新编译安装 Nginx ,如果没有该方面需求尽量不要做

# 操作如下:
1:修改源码包下的src/core/nginx.h  # 记得这里的"#"不是注释的意思哦
define NGINX_VERSION "9.9.9.9" # 修改为想要显示的版本号
define NGINX_VER "DLB/" NGINX_VERSION # 修改为想要显示的软件名

2:修改src/http/ngx_http_header_filter_module.c
static char ngx_http_server_string[] = "Server: DLB" CRLF; # 修改为想要显示的软件名
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

3:修改src/http/ngx_http_special_response.c
static u_char ngx_http_error_full_tail[] =
"

<center>" NGINX_VER "(www.google.com)</center>" CRLF # 此行定义对外展示的内容
"</body>" CRLF
"</html>" CRLF
;
static u_char ngx_http_error_tail[] =
"
<center>DLB</center>" CRLF # 此行定义对外展示的软件名
"</body>" CRLF
"</html>" CRLF
;

4:编译 Nginx
[root@virtual_host nginx-1.21.6]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
[root@virtual_host nginx-1.21.6]# make && make install
# 启动测试
[root@virtual_host sbin]# /usr/local/nginx/sbin/nginx     # 启动Nginx
[root@virtual_host sbin]# curl 127.0.0.1 -I
HTTP/1.1 200 OK
Server: DLB/9.9.9.9

3:修改Nginx的默认运行用户

# 优化原因:这个可能涉及到问题就非常的多了,比如nginx被入侵挂webshell之后获取的权限,我们可以设置一个低权限的用户只用于运行程序,防止被进一步渗透造成威胁,也有就是类似于我们可能会更改的22端口一样,保证我们服务的安全性方面。

# 操作如下:
1:添加用户
[root@virtual_host ~]# useradd -s /sbin/nologin -M nginx
2:更改 Nginx 配置文件
[root@virtual_host sbin]# grep -Ev "^$|#" /etc/nginx/nginx.conf
user nginx nginx;    # 指定Nginx服务的用户和用户组 这里可以有两个,一个数用户,一个是用户组
......
3:启动Nginx
[root@virtual_host sbin]# nginx
4:查看进程
[root@virtual_host sbin]# ps -ef | grep nginx
root      14527      1  0 13:24 ?        00:00:00 nginx: master process nginx
nginx     14528  14527  0 13:24 ?        00:00:00 nginx: worker process
# 这里有个问题,为什么我们的master进程还是root呢?留个问题给各思考下! 

4:优化 Nginx worker 进程数

# 优化原因:Nginx 有 Master 和 worker 两种进程,Master 进程用于管理 worker 进程,worker 进程用于 Nginx 服务,worker 进程数应该设置为等于 CPU 的核数,高流量并发场合也可以考虑将进程数提高至 CPU 核数 * 2

# 操作如下:
1:查看CPU核心数量
[root@virtual_host sbin]# grep -c processor /proc/cpuinfo   
1
2:设置worker进程数
[root@virtual_host sbin]# grep -Ev "^$|#" /etc/nginx/nginx.conf
user nginx;
worker_processes 2;  # 这里一般配置为CPU的核心数,但是高并发可以配置为CPU的核心数*2
3:重载测试
[root@virtual_host sbin]# nginx -s reload
[root@virtual_host sbin]# ps -ef | grep nginx
root      14527      1  0 13:24 ?        00:00:00 nginx: master process nginx
nginx     14587  14527  0 14:23 ?        00:00:00 nginx: worker process
nginx     14588  14527  0 14:23 ?        00:00:00 nginx: worker process

5:绑定 Nginx 进程给不同的 CPU

# 优化原因:默认情况下,Nginx 的多个进程有可能跑在某一个 CPU 或 CPU 的某一核上,导致 Nginx 进程使用硬件的资源不均,因此绑定 Nginx 进程到不同的 CPU 上是为了充分利用硬件的多 CPU 多核资源的目的。

# 操作如下
1:查看CPU核心数量
[root@virtual_host ~]# grep -c processor /proc/cpuinfo 
2
2:绑定CPU并配置核心数
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
user nginx;
worker_processes 2;  # 配置核心数,这里要设置和CPU相同的核心数
worker_cpu_affinity 01 10;  # 2核CPU配置
# 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;
3:测试(这里我选择AB压测一下)
[root@virtual_host ~]# top
  1168 nginx     20   0   39700   2068    692 S   4.0  0.2   0:00.43 nginx                                        
  1169 nginx     20   0   39700   2064    688 R   4.0  0.2   0:00.40 nginx
# 可以看到这里的进程处理是比较平均的

6:优化 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 多路复用模型

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
events {
    worker_connections 1024;
    use epoll;   # 针对于Linux平台
}
---

7:优化 Nginx 单个进程允许的最大连接数

# 优化原因:
# 1:控制 Nginx 单个进程允许的最大连接数的参数为 worker_connections ,这个参数要根据服务器性能和内存使用量来调整
# 2:进程的最大连接数受 Linux 系统进程的最大打开文件数限制,只有执行了 “ulimit -HSn 65535” 之后,worker_connections 才能生效
# 3:连接数包括代理服务器的连接、客户端的连接等,Nginx 总并发连接数 = worker 数量 * worker_connections, 总数保持在3w左右

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
events {
    worker_connections 10240; # 单进程最大连接10240(根据实际应用优化)
    use epoll;
}
---

8:优化 Nginx worker 进程最大打开文件数

# 操作如下
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
user nginx;
worker_processes 2;
worker_cpu_affinity 01 10;
worker_rlimit_nofile 65535; # worker 进程最大打开文件数,可设置为优化后的 ulimit -HSn 的结果

9:优化服务器域名的散列表大小

# 优化原因:如果在 server_name 中配置了一个很长的域名,那么重载 Nginx 时会报错,因此需要使用 server_names_hash_max_size 来解决域名过长的问题,该参数的作用是设置存放域名的最大散列表的存储的大小,根据 CPU 的一级缓存大小来设置。
# 现版本已经基本都不存在这个问题了

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    server {
        listen       80;
        server_name  www.abcdesfgjrwbgjrwbgbdwjgnwjgirwngiowmnopqrstuvwxyz.com;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
---
重载报错
nginx: [emerg] could not build the server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: configuration file /etc/nginx/nginx.conf test failed
 
# 添加配置

server_names_hash_bucket_size  512;  # 配置在 http 区块,默认是 512kb ,一般设置为 cpu 一级缓存的 4-5 倍,一级缓存大小可以用 lscpu 命令查看
[root@virtual_host ~]# lscpu | grep L1d
L1d cache:             32K
也就是 32*5

10:开启高效文件传输模式

# 优化原因:
# 1:sendfile 参数用于开启文件的高效传输模式,该参数实际上是激活了 sendfile() 功能,sendfile() 是作用于两个文件描述符之间的数据拷贝函数,这个拷贝操作是在内核之中的,被称为 “零拷贝” ,sendfile() 比 read 和 write 函数要高效得多,因为 read 和 write 函数要把数据拷贝到应用层再进行操作
# 2:tcp_nopush 参数用于激活 Linux 上的 TCP_CORK socket 选项,此选项仅仅当开启 sendfile 时才生效,tcp_nopush 参数可以允许把 http response header 和文件的开始部分放在一个文件里发布,以减少网络报文段的数量

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    sendfile            on;   # 开启文件的高效传输模式
    tcp_nopush          on;   # 激活 TCP_CORK socket 选择
    tcp_nodelay         on;   # 数据在传输的过程中不进缓存
---

11:优化 Nginx 连接超时时间

1:什么是连接超时
	1.1:当你用美团外卖点单,虽然你点单了,这个时候等于是你的请求达到了Nginx服务器
	1.2:但是因为你点的单太远了或者没有骑手接单,这里指建立的连接没有发送请求,然后在一定时间内您的订单将被取消
2:连接超时的作用
	2.1:将无用的连接设置为尽快超时,可以保护服务器的系统资源(CPU、内存、磁盘)
3:当连接很多时,及时断掉那些建立好的但又长时间不做事的连接,以减少其占用的服务器资源
4:如果黑客攻击,会不断地和服务器建立连接,因此设置连接超时以防止大量消耗服务器的资源
5:如果用户请求了动态服务,则 Nginx 就会建立连接,请求 FastCGI 服务以及后端 MySQL 服务,设置连接超时,使得在用户容忍的时间内返回数据
6:连接超时存在的问题
	6.1:服务器建立新连接是要消耗资源的,因此,连接超时时间不宜设置得太短,否则会造成并发很大,导致服务器瞬间无法响应用户的请求
	6.2:有些 PHP 站点会希望设置成短连接,因为 PHP 程序建立连接消耗的资源和时间相对要少些
	6.3:有些 Java 站点会希望设置成长连接,因为 Java 程序建立连接消耗的资源和时间要多一些,这时由语言的运行机制决定的
7:设置连接超时
	7.1:keepalive_timeout :该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接
	7.2:client_header_timeout :该参数用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 “Request time out (408)” 错误
	7.3:client_body_timeout :该参数用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 “Request time out (408)” 错误
	7.4:send_timeout :用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任何活动,Nginx 将会关闭连接
	7.5:tcp_nodelay :默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长

# 操作如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    keepalive_timeout   65;
    tcp_nodelay on;
    client_header_timeout 15;
    client_body_timeout 15;
    send_timeout 25;
---

12:限制上传文件的大小

# 优化原因:因为我们可能有些时候涉及到上传一些头头像,小文件等等的,但是可能有不怀好意的人上传大文件占用存储,所以这里可以做一个限制大小的操作,但是现在的开发在后端就做这个操作了

client_max_body_size 用于设置最大的允许客户端请求主体的大小,在请求首部中有 “Content-Length”
如果超过了此配置项,客户端会收到 413 错误,即请求的条目过大

# 操作如下
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    client_max_body_size 1m;  # 设置客户端最大的请求主体大小为1M
---

13:FastCGI 相关参数调优

# 当 LNMP 组合工作时,首先是用户通过浏览器输入域名请求 Nginx Web 服务,如果请求的是静态资源,则由 Nginx 解析返回给用户;如果是动态请求(如 PHP),那么 Nginx 就会把它通过 FastCGI 接口发送给 PHP 引擎服务(即 php-fpm)进行解析,如果这个动态请求要读取数据库数据,那么 PHP 就会继续向后请求 MySQL 数据库,以读取需要的数据,并最终通过 Nginx 服务把获取的数据返回给用户,这就是 LNMP 环境的基本请求流程。

# 什么是FastCGI
FastCGI 介绍:CGI 通用网关接口,是 HTTP 服务器与其他机器上的程序服务通信交流的一种工具,CGI 接口的性能较差,每次 HTTP 服务器遇到动态程序时都需要重新启动解析器来执行解析,之后结果才会被返回 HTTP 服务器,因此就有了 FastCGI ,FastCGI 是一个在 HTTP 服务器和动态脚本语言间通信的接口,主要是把动态语言和 HTTP 服务器分离开来,使得 HTTP 服务器专一地处理静态请求,提高整体性能,在 Linux 下,FastCGI 接口即为 socket ,这个 socket 可以是文件 socket 也可以是 IP socket

# 配置如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    fastcgi_connect_timeout  240; # Nginx服务器和后端FastCGI服务器连接的超时时间
    fastcgi_send_timeout     240; # Nginx允许FastCGI服务器返回数据的超时时间,即在规定时间内后端服务器必须传完所有的数据,否则Nginx将断开这个连接
    fastcgi_read_timeout     240; # Nginx从FastCGI服务器读取响应信息的超时时间,表示连接建立成功后,Nginx等待后端服务器的响应时间
    fastcgi_buffer_size      64k; # Nginx FastCGI 的缓冲区大小,用来读取从FastCGI服务器端收到的第一部分响应信息的缓冲区大小
    fastcgi_buffers        4 64k; # 设定用来读取从FastCGI服务器端收到的响应信息的缓冲区大小和缓冲区数量
    fastcgi_busy_buffers_size    128k; # 用于设置系统很忙时可以使用的 proxy_buffers 大小
    fastcgi_temp_file_write_size 128k; # FastCGI 临时文件的大小
---

fastcti_temp_path  # FastCGI 临时文件的存放路径

# 配置如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
fastcgi_cache_path     /etc/nginx/ngx_fcgi_cache  levels=2:2  keys_zone=ngx_fcgi_cache:512m  inactive=1d  max_size=40g;    # 缓存目录

server {
    listen       80;
    server_name  www.devopsdu.com;
    location / {
        root   html/www;
        index  index.html index.htm;
    }
    location ~ .*\.(php|php5)?$ {
        root            html/www;
        fastcgi_pass    127.0.0.1:9000;
        fastcgi_index   index.php;
        include         fastcgi.conf;
        fastcgi_cache   ngx_fcgi_cache;            # 缓存FastCGI生成的内容,比如PHP生成的动态内容
        fastcgi_cache_valid      200  302  1h;     # 指定http状态码的缓存时间,这里表示将200和302缓存1小时
        fastcgi_cache_valid      301  1d;          # 指定http状态码的缓存时间,这里表示将301缓存1天
        fastcgi_cache_valid      any  1m;          # 指定http状态码的缓存时间,这里表示将其他状态码缓存1分钟
        fastcgi_cache_min_uses   1;                # 设置请求几次之后响应被缓存,1表示一次即被缓存
        fastcgi_cache_use_stale  error  timeout  invalid_header  http_500;    # 定义在哪些情况下使用过期缓存
        fastcgi_cache_key        http://$host$request_uri;                    # 定义 fastcgi_cache 的 key
    }
}
---

14:配置 Nginx gzip 压缩

# 优化原因:Nginx gzip 压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到客户端之前,Nginx 服务器会根据一些具体的策略实施压缩,以节约网站出口带宽,同时加快数据传输效率,来提升用户访问体验,需要压缩的对象有 html 、js 、css 、xml 、shtml ,图片和视频尽量不要压缩,因为这些文件大多都是已经压缩过的,如果再压缩可能反而变大,另外,压缩的对象必须大于 1KB,由于压缩算法的特殊原因,极小的文件压缩后可能反而变大

# 配置如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
gzip  on;                    # 开启压缩功能
gzip_min_length  1k;         # 允许压缩的对象的最小字节
gzip_buffers  4 32k;         # 压缩缓冲区大小,表示申请4个单位为16k的内存作为压缩结果的缓存
gzip_http_version  1.1;      # 压缩版本,用于设置识别HTTP协议版本
gzip_comp_level  9;          # 压缩级别,1级压缩比最小但处理速度最快,9级压缩比最高但处理速度最慢
gzip_types  text/css text/xml application/javascript;    # 允许压缩的媒体类型
gzip_vary  on;               # 该选项可以让前端的缓存服务器缓存经过gzip压缩的页面,例如用代理服务器缓存经过Nginx压缩的数据
---

image

15:配置 Nginx expires 缓存

1:Nginx expires 的功能就是为用户访问的网站内容设定一个过期时间,当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及以后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器下载了,直到缓存的内容过期或被清除为止
2:不希望被缓存的内容:广告图片、网站流量统计工具、更新很频繁的文件
3:缓存日期参考:51CTO 缓存 1 周,新浪缓存 15 天,京东缓存 25 年,淘宝缓存 10 年

# 配置如下:
[root@virtual_host ~]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    server {
        listen       80;
        server_name  www.devopsdu.com;
        root         /usr/share/nginx/html;
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {  # 缓存的对象
            expires     3650d;   # 缓存的时间,3650天,即10年
        }
    }
---

1image

16:优化 Nginx access 日志

# 日志切割:
[root@virtual_host ngx_script]# cat nginx_log_cut.sh 
#!/bin/bash
logs_cut_data='/etc/nginx/logs'
logs_nginx_log='/var/log/nginx/'
logs_times=$(date -d "yesterday" +%Y-%m-%d)
create_dir (){
    mkdir -p $logs_cut_data
}

if [ ! -d $logs_cut_data ];then
    creater_dir
else
    mv $logs_nginx_log/access.log $logs_cut_data/access.$logs_times.log
    mv $logs_nginx_log/error.log $logs_cut_data/error.$logs_times.log
    if [ -f /var/run/nginx.pid ];then
        /usr/sbin/nginx -s stop
        /usr/sbin/nginx
    else
        /usr/sbin/nginx
    fi
fi

crontab -e # 每天凌晨0点执行脚本 (记得给脚本添加执行权限哦)
0 */24 * * * /etc/nginx/ngx_script/nginx_log_cut.sh

# 如果某些server下的location不需要记录日志,我们可以通过如下方式配置不记录日志
[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    server {
        listen       80;
        server_name  www.devopsdu.com;
        root         /usr/share/nginx/html;
        location / {
            access_log    off;
        }
    }
---

17:优化 Nginx 站点目录

# 优化原因:可能涉及到安全,被恶意执行脚本

1:禁止解析指定目录下的指定程序
[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
        location ^/.*.(php|php5|sh|pl|py)$ {
            deny    all;
        }
---
# 根据实际来禁止哪些目录下的程序,且该配置必须写在 Nginx 解析 PHP 的配置前面

2:限制IP或网段访问
[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
        location ^/.*.(php|php5|sh|pl|py)$ {
            allow 10.0.0.0/8;       # 允许的网段
            deny all;               # 拒绝所有,(这里可以按照防火墙的规则匹配来操作,会有优先级的问题)
        }
---

18:使用Nginx解决盗链问题

# 优化原因:什么是防盗链:简单地说,就是某些不法网站未经许可,通过在其自身网站程序里非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,使得被盗链的那一端消耗带宽资源 (1) 根据 HTTP referer 实现防盗链:referer 是 HTTP的一个首部字段,用于指明用户请求的 URL 是从哪个页面通过链接跳转过来的

# 根据 cookie 实现防盗链:cookie 是服务器贴在客户端身上的 “标签” ,服务器用它来识别客户端

1:根据 referer 配置防盗链
	1.1:匹配后缀
	[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
	---
	location ~ .*.(gif|jpg|jpeg|png|bm|swf|flv|rar|zip|gz|bz2)$ {
	    access_log  off;      # 不记录防盗链的日志
        expires  15d;         # 设置缓存时间
	    valid_referers  none  blocked  img.kubernetes-devops.cn  *.kubernetes-devops.cn;  # 表示这些地址可以访问上面的媒体资源
        if ($invalid_referer) {       # 如果地址不是上面指定的地址就返回403
            return 403;
        }
	}
	---
	
2:绑定目录
[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
        location /img {
            root /usr/share/nginx/images;
            valid_referers  none  blocked  img.kubernetes-devops.cn  *.kubernetes-devops.cn;
            if ($invalid_referer) {
                return 403;
            }
        }
---

19:配置 Nginx 错误页面优雅显示

[root@virtual_host ngx_script]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
        location / {
            root    /usr/share/nginx/html;
            index  index.html index.htm;
            error_page 400 401 402 403 404 405 408 410 412 413 414 415 500 501 502 503 = https://error.kubernetes-devops.cn/error.html;
        }
---

20:优化 Nginx 文件权限

# 优化原因:为了保证网站不受木马入侵,所有文件的用户和组都应该为 root ,所有目录的权限是 755 ,所有文件的权限是 644
[root@virtual_host ngx_script]# chown -R root:root /etc/nginx/     # 更改属主属组
[root@virtual_host nginx]# find /etc/nginx/ -type d | xargs chmod 755    # 更改目录权限
[root@virtual_host nginx]# find /etc/nginx/ -type f | xargs chmod 644    # 更改文件权限
# 这个方法也针对 nginx内配置的所有网页目录等等......

21:防爬优化

# 优化原因:很好理解,Nginx做大力的时候为了防止爬虫,所以可以使用此方法来预防一部分,我们可以根据客户端的 user-agents 首部字段来阻止指定的爬虫爬取我们的网站

# 操作如下:
[root@virtual_host nginx]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
        location /files {
            if $http_user_agent ~* ("Adsbot-Google|Yahoo! Slurp China|Sosospider|Sogou spider|Sogou web spider") {
                return 403;
            }
        }
---

22:控制Nginx并发数

# 限制单个 IP 的并发连接数
[root@virtual_host nginx]# grep -Ev "^$|#" /etc/nginx/conf.d/web.conf 
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
limit_conn_zone $binary_remote_addr zone=addr:10m;  # 用于设置共享内存区域,addr 是共享内存区域的名称,10m 表示共享内存区域的大小
server {
    server_name  www.kubernetes-devops.cn;
    location / {
        root    /usr/share/nginx/html;
        index index.html index.htm;
        limit_conn addr 1;     # 限制单个IP的并发连接数为1
}

# 限制虚拟主机总连接数
include       mime.types;
default_type  application/octet-stream;
sendfile        on;
keepalive_timeout  65;
limit_conn_zone $server_name zone=perserver:10m;
server {
    server_name  www.kubernetes-devops.cn;
    location / {
        root    /usr/share/nginx/html;
        index index.html index.htm;
        limit_conn perserver 2;    # 设置虚拟主机连接数为2
}

# 集群代理优化
# 会话保持(当服务器集群中没有会话池时,且代理的是动态数据就必须写ip_hash,反之什么也不用写)
# fair   #智能分配(第三方,需要下载upstream_fair模块)根据后端服务器的响应时间来调度
# url_hash   #更具URL的结果来分配请求(每个url定向到同一个服务器,提高后端缓存服务器的效率,本身不支持,需要安装nginx_hash)
#当算法为ip_hash不能有 weight backup
[root@virtual_host nginx]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    upstream services {
        server 10.0.0.10:8080;   # 默认weight为1
        server 10.0.0.11:8080 weight=5;    # weight表示权重
        server 10.0.0.12:8080 down;     # down不参与本次轮询
        server 10.0.0.13:8080 down backup;  # backup当任何一台主机出现故障,将进行切换替换
        server 10.0.0.14:8080 max_fails=3 fail_timeout=20s;  # max_fails最大失败请求次数(默认为1),fail_timeout失败超时时间
    }
---
# 整个配置如下
# hash $remote_addr consistent; //保持 session 不变,四层开启
[root@virtual_host nginx]# grep -Ev "^$|#" /etc/nginx/nginx.conf
---
    upstream services {
        # hash $remote_addr consistent;   # 保持 session 不变,四层开启
        server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;
        server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
    }
    server {
        listen 80;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass services;
        location / {
            proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header;  # 当发生其中任何一种错误,将转交给下一个服务器
            proxy_redirect off;
            proxy_set_header Host $host;    # 设置后端服务器的真实地址
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
            client_body_buffer_size 128k;   # 缓冲区大小,本地保存大小
            proxy_connect_timeout 90;       # 发起握手等待的响应时间
            proxy_read_timeout 90;          # 建立连接后等待后端服务器响应时间(其实是后端等候处理的时间)
            proxy_send_timeout 90;          # 给定时间内后端服务器必须响应,否则断开
            proxy_buffer_size 4k;           # proxy缓冲区大小
            proxy_buffers 4 32k;            # 缓冲区个数和大小
            proxy_busy_buffers_size 64k;    # 系统繁忙时buffer的临时大小,官方要求proxy_buffer_size*2
            proxy_temp_file_write_size 64k; # proxy临时文件的大小
        }
    }
---

23:Linux内核优化

net.ipv4.tcp_syncookies = 1
fs.file-max = 999999
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.core.somaxconn=262114
net.core.netdev_max_backlog=262114
net.ipv4.tcp_max_syn_backlog = 262114
net.ipv4.tcp_max_orphans=262114
net.ipv4.tcp_synack_retries=1
net.ipv4.tcp_syn_retries=1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_fin_timeout = 30
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 10240 87380 12582912
net.ipv4.tcp_wmem = 10240 87380 12582912
net.core.netdev_max_backlog = 8096
net.core.rmem_default = 6291456
net.core.wmem_default = 6291456
net.core.rmem_max = 12582912
net.core.wmem_max = 12582912

# 参数解析
net.ipv4.tcp_syncookies = 1                # 选项用于设置开启SYN cookies,当出现SYN等待队列溢出时,启用cookies进行处理
fs.file-max = 999999                       # 这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直线限制最大并发连接数,需根据实际情况配置
net.ipv4.tcp_max_tw_buckets =6000          # 这个参数用来设定timewait数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180 000,过多的TIME_WAIT套接字会使Web服务器变慢
net.ipv4.tcp_tw_recycle=1                  # 这个参数用于设置启用timewait快速回收
net.ipv4.tcp_tw_reuse = 1                  # 这个参数设置为1,表示允许将TIME-WAIT状态的socket重新用于新的TCP连接,这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接
net.core.somaxconn=262114                  # 选项默认值是128,这个参数用于调节系统同时发起的TCP连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合高并发请求数来调节此值
net.core.netdev_max_backlog=262114         # 该选项表示每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列数据包的最大数目
net.ipv4.tcp_max_syn_backlog =262114       # 这个参数表示TCP三次握手建立阶段接受SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求
net.ipv4.tcp_max_orphans=262114            # 选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立链接将立即被复位并输出警告信息。这个限制指示为了防止简单的DOS攻击,不用过分依靠这个限制甚至认为的减小这个值,更多的情况是增加这个值
net.ipv4.tcp_synack_retries=1              # 内核放弃连接之前发送SYN+ACK包的数量
net.ipv4.tcp_syn_retries=1                 # 内核放弃连接之前发送SYN包的数量
net.ipv4.tcp_keepalive_time = 600          # 这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置的小一些,可以更快地清理无效的连接
net.ipv4.tcp_fin_timeout = 30              # 这个参数表示当服务器主动关闭连接时,socket保持在FIN-WAIT-2状态的最大时间
net.ipv4.ip_local_port_range = 1024 61000  # 这个参数定义了在UDP和TCP连接中本地(不包括连接的远端)端口的取值范围
net.ipv4.tcp_rmem = 10240 87380 12582912   # 这个参数定义了TCP接受缓存(用于TCP接受滑动窗口)的最小值、默认值、最大值
net.core.netdev_max_backlog = 8096         # 当网卡接受数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。这个参数表示该队列的最大值
net.core.rmem_default = 6291456            # 这个参数表示内核套接字接受缓存区默认的大小
net.core.wmem_default = 6291456            # 这个参数表示内核套接字发送缓存区默认的大小
net.core.rmem_max = 12582912               # 这个参数表示内核套接字接受缓存区的最大大小
net.core.wmem_max = 12582912               # 这个参数表示内核套接字发送缓存区的最大大小
net.ipv4.tcp_syncookies = 1                # 该参数与性能无关,用于解决TCP的SYN攻击

# 注:滑动窗口的大小与套接字缓存区会在一定程度上影响并发连接的数目。每个TCP连接都会为维护TCP滑动窗口而消耗内存,这个窗口会根据服务器的处理速度收缩或扩张。 参数net.core.wmem_max = 12582912的设置,需要平衡物理内存的总大小、Nginx并发处理的最大连接数量而确定。当然,如果仅仅为了提供并发量使服务器不出现Out Of Memory问题而去降低滑动窗口大小,那么并不合适,因为滑动窗过小会影响大数据量的传输速度。net.core.rmem_default = 6291456、net.core.wmem_default = 6291456、 net.core.rmem_max = 12582912和net.core.wmem_max = 12582912这4个参数的设置需要根据我们的业务特性以及实际的硬件成本来综合考虑。 Nginx并发处理的最大连接量:由nginx.conf中的work_processes和work_connections参数决定
posted @ 2022-06-12 16:18  Layzer  阅读(80)  评论(0编辑  收藏  举报