zoukankan      html  css  js  c++  java
  • nginx性能优化(针对于高并发量仅供参考,并不是方案)

    关于nginx.conf中的优化

    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>
    //每个进程在重置之前能够执行的最多请求数。
    

    后记:

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

  • 相关阅读:
    用手机管理及维护MySQL,Oracle等数据库
    MySQL数据导出为Excel, json,sql等格式
    sql server web管理软件
    mysql数据导入mongoDB
    robot framework接口测试之一-完整的测试用例
    Git常用命令
    robot framework学习笔记之三—Scalar变量
    robot framework学习笔记之二———变量
    robot framework学习笔记之一 资源文件(Resource)和外部资源(External Resources)
    浏览器缓存机制
  • 原文地址:https://www.cnblogs.com/jojoword/p/10764483.html
Copyright © 2011-2022 走看看