nginx性能优化(针对于高并发量仅供参考,并不是方案) 关于nginx.conf中的优化 关于内核参数的优化: 关于 FastCGI 的几个指令: 后记:

nginx性能优化(针对于高并发量仅供参考,并不是方案)
关于nginx.conf中的优化
关于内核参数的优化:
关于 FastCGI 的几个指令:
后记:

1.worker_processes 4;
//nginx 进程数,建议按照 cpu 数目来指定,一般为它的倍数。

2.worker_cpu_affinity 0100 1000 0010 0001;
//为每个进程分配cpu,上例中将 4 个进程分配到 4个cpu.

  worker_cpu_affinity 0101 1010;
//或者将一个进程分配到多个 cpu。

3.worker_rlimit_nofile 102400;
//这个指令是指当一个 nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与 nginx 进程数相除,但是 nginx 分配请求并不是那么均匀,所以最好与 ulimit -n 的值保持一致。

4.use epoll;
//使用 epoll 的 I/O 模型,这个不用说了吧。

5.worker_connections 102400;
//每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processes*worker_connections。

6.keepalive_timeout 60;
//keepalive 超时时间。

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

8.open_file_cache max=102400 inactive=20s;
//这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。

9.open_file_cache_valid 30s;
//这个是指多长时间检查一次缓存的有效信息。

10.open_file_cache_min_uses 1;
//open_file_cache 指令中的 inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在 inactive 时间内一次没被使用,它将被移除。

配置nginx客户端网页缓存本地时间

修改主配置文件nginx.conf

49         location ~ .(gif|jpg|jpeg|png|bmp|ico)$ {
50             expires 1d;
51         }
52         #匹配以上文件格式的在客户本地缓存一天
53         location ~ .*.(mp3|flac)$ {
54             expires 1h;
55         }
		    #匹配格式的本地缓存1小时

nginx日志切割

使用shell脚本+crontab
[root@localhost html]# vim /opt/cut_nginx_log.sh
    #!/bin/bash
    #00:00 excute this script
    
    datetime=$(date -d "-1 day" "+%Y%m%d")
    #该变量定义日志命名后跟的时间戳,因为是每天00:00运行,但日志记录的是前一天的记录,所以天数-1
    
    log_path="/usr/local/nginx/logs"
    pid_path="$log_path/nginx.pid"
    
    [ -d $log_path/backup ] || mkdir -p $log_path/backup
    #没有该目录则新建
    
    if [ -f $pid_path ]
    then
            mv $log_path/access.log $log_path/backup/access.log-$datetime
            kill -USR1 $(cat $pid_path)
            #产生新的日志文件
    
            find $log_path/backup -mtime +30 | xargs rm -f
            #mtime代表着最近一次文件内容被修改的时间,即将30天以前的文件删除掉
    
    else    
            echo "Error,Nginx is not working!" | tee -a /var/log/messages
    fi
[root@localhost html]# crontab -e
0 0 * * *  /bin/bash /opt/cut_nginx_log.sh

nginx连接超时优化

[root@localhost html]# vim /opt/cut_nginx_log.sh
    21     keepalive_timeout 65;
    22     #该参数用于设置客户端连接保持会话的超时时间,超过这个时间服务器会关闭该连接
    
    23     tcp_nodelay on;
    24     #默认情况下当数据发送时,内核并不会马上发送,可能会等待更多的字节组成一个数据包,这样可以提高 I/O 性能,但是,在每次只发送很少字节的业务场景中,使用 tcp_nodelay 功能,等待时间会比较长
    
    25     client_header_timeout 15;
    26     #该参数用于设置读取客户端请求头数据的超时时间,如果超时客户端还没有发送完整的 header 数据,服务器将返回 "Request time out (408)" 错误
    
    27     client_body_timeout 15;
    28     #该参数用于设置读取客户端请求主体数据的超时时间,如果超时客户端还没有发送完整的主体数据,服务器将返回 "Request time out (408)" 错误
    
    29     send_timeout 25;
    30     #用于指定响应客户端的超时时间,如果超过这个时间,客户端没有任活动,Nginx 将会关闭连接

Nginx 实现网页压缩功能

[root@localhost html]# vim /opt/cut_nginx_log.sh
    46     gzip  on;
    47     #开启 gzip 压缩输出
    
    48     gzip_buffers 4 16k;
    49     #表示申请 4 个单位为 16k 的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来储存 gzip 压缩结果
    
    50     gzip_http_version 1.0 | 1.1;
    51     #对使用htto协议1.0和1.1的请求进行压缩;早期的一些浏览器或者http客户端可能不支持gzip压缩,因此有客户有时候会看到乱码,那是应为客户端无法进行解
       压,因此可以根据不同的http协议版本进行选择性的打开或关闭gzip功能;
       
    52     gzip_min_length 1024;
    53     #默认为20,建议设置位1KB,如果设置为0则表示压缩全部数据包;设置最少压缩的数据包大小,小于此值的数据包将不被压缩,因为大量的小的数据压缩后没有
       明显的效果还占用了CPU的资源,因此可以设置最少多大的数据才进行压缩
       
    54     gzip_comp_level 4;
    55     #推荐先设置为中间的值,比如4或者5;指定gzip压缩级别,级别为1-9,默认为1,级别越高压缩率越高即压缩后的文件越小,但是越占用CPU,压缩率越小压缩后的文件越大,但是节约CPU。 
    
    56     gzip_types       text/plain application/x-javascript text/css application/xml;
    57     #对哪些文档进行压缩;设置Nginx服务器可以根据响应页面的类型进行选择性的打开或关闭gzip功能
    
    58     gzip_vary on;
    59     #用于设置是否在使用gzip功能时发送带有"vary:Accept-Encoding" 头域的响应头部,该头域的主要功能时要告诉客户端数据已经在服务器进行了压缩,默认设
       置为off;还可以使用Nginx配置的add_header指令强制在Nginx服务器的响应头部添加“Vary:Accept-Encding”也可以实现相同的效果。

Nginx 实现防盗链功能

[root@localhost html]# vim nginx.conf
    79         location ~ .*.(gif|jpg|jpeg|png|bm|swf|flv|rar|zip|gz|bz2)$ {
    80         # 指定需要使用防盗链的媒体资源
    81 
    82             access_log off;
    83             # 不记录防盗链的日志
    84             expires 15d;
    85             # 设置缓存时间
    86             valid_referers none blocked *.test.com *.abc.com;
    87             # 表示这些地址可以访问上面的媒体资源, (*代表任何,任何的二级域名)
    88             if ($invalid_referer) {
    89             # 如果地址不如上面指定的地址就返回403
    90             return 403
    91         }

为目录添加访问控制

需要用到apache的htpasswd工具
[root@localhost nginx-1.15.9]# htpasswd -bc /usr/local/nginx/.htpasswd join best
//在该路径生成该文件 用户名为qiao
//-c:创建一个加密文件;
//-n:不更新加密文件,只将加密后的用户名密码显示在屏幕上;
//-m:默认采用MD5算法对密码进行加密;
//-d:采用CRYPT算法对密码进行加密;
//-p:不对密码进行进行加密,即明文密码;
//-s:采用SHA算法对密码进行加密;
//-b:在命令行中一并输入用户名和密码而不是根据提示输入密码;
//-D:删除指定的用户。

[root@localhost nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf
    48         location ~ /status{
    49         stub_status on;
    50         #开启状态检测
    51         access_log off;
    52         #不将访问该项写入日志
    53         auth_basic "yours status auth";
    54         #出现的提示信息
    55         auth_basic_user_file /usr/local/nginx/.htpasswd;
    56         #指定认证文件
    57         }

客户端地址的访问控制
location / {
   	 	deny  192.168.1.1;
    		allow 192.168.1.0/24;
    		allow 10.1.1.0/16;
    		allow 2001:0db8::/32;
    		deny  all;
}
#从上至下逐条匹配,可以设置基于http、server、location和limit_except

自定义nginx访问错误页面

[root@localhost nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf
    58         }
    59         error_page  404              /404.html;
    60         location = /404.html{
    61                 root html;
    62         }
// 从上面可以看出,如果访问我定义的server出现404,403,500,502,503,504 错误时,直接nginx重写到 location = /404.html ,在这个location中,我定义root,也就是我们自己定义的错误页面所在的位置,这里是/usr/lcoal/nginx/html/然后我们在这个路径下vim 404.html就可以了 。

nginx索引目录配置

[root@localhost nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf

    location /download {
                    autoindex on; 
    #开启自动索引功能
                    autoindex_localtime on;
    #开启显示目录或文件的时间功能
            }
    //访问http://domainname/download匹配该索引

nginx目录别名

[root@localhost nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf

比如nginx配置的域名是www.root.com
    location /join/ {
         		 alias /usr/local/data/qiao/;
    }
//如用户访问www.root.com/join/index.html将会转到/usr/local/data/qiao/index.html
//如果是给目录创建别名,则/符号必须要有;如果是文件则配置的有/,用户访问时也要有/,配置没有/,则用户没有/,也会自动加上,不影响访问

nginx实现手机端和电脑端的分离网页

HTTP请求的Header中的User-Agent可以区分客户端的浏览器类型,可以通过User-Agent来判断客户端的设备。
[root@localhost nginx-1.15.9]# vim /usr/local/nginx/conf/nginx.conf
set $mobile_rewrite do_not_perform;
#设置该变量的初始值
if ($http_user_agent ~* "(android|bbd+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
  set $mobile_rewrite perform;
}

if ($http_user_agent ~* "^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw-(n|u)|c55/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do(c|p)o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(-|_)|g1 u|g560|gene|gf-5|g-mo|go(.w|od)|gr(ad|un)|haie|hcit|hd-(m|p|t)|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c(-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac( |-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk/|se(c(-|0|1)|47|mc|nd|ri)|sgh-|shar|sie(-|m)|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel(i|m)|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-)") {
  set $mobile_rewrite perform;
}

if ($mobile_rewrite = perform) {
   #Nginx通过以上的配置,获取HTTP请求的User-Agent,使用正则表达式来匹配手机设备。
}
location / {
	root html/pc;
	#电脑版页面
	if ($mobile_rewrite = perform) {
	root html/mobile;
	#如果条件符合,判断为手机浏览器,转到手机页面
	}
}

关于内核参数的优化:

1.net.ipv4.tcp_max_tw_buckets = 6000
//timewait 的数量,默认是 180000。

2.net.ipv4.ip_local_port_range = 1024	65000
//允许系统打开的端口范围。

3.net.ipv4.tcp_tw_recycle = 1
//启用 timewait 快速回收。

4.net.ipv4.tcp_tw_reuse = 1
//开启重用。允许将 TIME-WAIT sockets 重新用于新的 TCP 连接。

5.net.ipv4.tcp_syncookies = 1
//开启 SYN Cookies,当出现 SYN 等待队列溢出时,启用 cookies 来处理。

6.net.core.somaxconn = 262144
//web 应用中 listen 函数的 backlog默认会给我们内核参数的net.core.somaxconn 限制到128,而 nginx 定义的 NGX_LISTEN_BACKLOG 默认为 511,所以有必要调整这个值。

7.net.core.netdev_max_backlog = 262144
//每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列数据包的最大数目。

8.net.ipv4.tcp_max_orphans = 262144
//系统中最多有多少个 TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的 DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。

9.net.ipv4.tcp_max_syn_backlog = 262144
//记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有 128M内存的系统而言,缺省值是 1024,小内存的系统则是 128。

10.net.ipv4.tcp_timestamps = 0
//时间戳可以避免序列号的卷绕。一个 1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。

11.net.ipv4.tcp_synack_retries = 1
//为了打开对端的连接,内核需要发送一个 SYN 并附带一个回应前面一个 SYN 的 ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送 SYN+ACK 包的数量。

12.net.ipv4.tcp_syn_retries = 1
//在内核放弃建立连接之前发送 SYN 包的数量。

13.net.ipv4.tcp_fin_timeout = 1
//如果套接字由本端要求关闭,这个参数决定了它保持在 FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是 60 秒。2.2 内核的通常值是 180 秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的 WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比 FIN-WAIT-1 要小,因为它最多只能吃掉 1.5K 内存,但是它们的生存期长些。

14.net.ipv4.tcp_keepalive_time = 30
//当 keepalive 起用的时候,TCP 发送 keepalive 消息的频度。缺省是 2 小时。

关于 FastCGI 的几个指令:

fastcgi_cache_path
/usr/local/nginx/fastcgi_cache
levels=1:2
keys_zone=TEST:10m

inactive=5m;
//这个指令为 FastCGI 缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。

fastcgi_connect_timeout 300;
//指定连接到后端 FastCGI 的超时时间。

fastcgi_send_timeout 300;
//向 FastCGI 传送请求的超时时间,这个值是指已经完成两次握手后向 FastCGI 传送请求的超时时间。

fastcgi_read_timeout 300;
//接收 FastCGI 应答的超时时间,这个值是指已经完成两次握手后接收 FastCGI 应答的超时时间。

fastcgi_buffer_size 4k;
//指定读取 FastCGI 应答第一部分需要用多大的缓冲区,一般第一部分应答不会超过 1k,由于页面大小为 4k,所以这里设置为 4k。

fastcgi_buffers 8 4k;
//指定本地需要用多少和多大的缓冲区来缓冲 FastCGI 的应答。

fastcgi_busy_buffers_size 8k;
//这个指令我也不知道是做什么用,只知道默认值是 fastcgi_buffers 的两倍。

fastcgi_temp_file_write_size 8k;
//在写入 fastcgi_temp_path 时将用多大的数据块,默认值是 fastcgi_buffers 的两倍。

fastcgi_cache TEST
//开启 FastCGI 缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU 负载,并且防止 502 错误。

fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
//为指定的应答代码指定缓存时间,如上例中将 200,302 应答缓存一小时,301 应答缓存 1 天,其他为 1 分钟。

fastcgi_cache_min_uses 1;
//缓存在 fastcgi_cache_path 指令inactive参数值时间内的最少使用次数,如上例,如果在5 分钟内某文件 1 次也没有被使用,那么这个文件将被移除。

fastcgi_cache_use_stale error timeout invalid_header http_500;
//不知道这个参数的作用,猜想应该是让 nginx 知道哪些类型的缓存是没用的。以上为 nginx 中 FastCGI 相关参数,另外,FastCGI 自身也有一些配置需要进行优化.

如果你使用 php-fpm 来管理 FastCGI,可以修改配置文件中的以下值:

<value name="max_children">60</value>
//同时处理的并发请求数,即它将开启最多 60 个子线程来处理并发连接。
<value name="rlimit_files">102400</value>
//最多打开文件数。
<value name="max_requests">204800</value>
//每个进程在重置之前能够执行的最多请求数。

后记:

本文是笔者亲自整理,但是参考了各大博客的各位前辈的许多智慧结晶,就不一一贴上链接了,如有侵权,留言即可,作者将会核实并且删除