• Nginx性能优化(超详细)


    目录

    一、性能优化考虑点

    一、当前系统结构瓶颈

    二、了解业务模式

    三、系统与Nginx性能优化

    1、文件句柄

    (1)设置方式

    (2)系统全局性修改和用户局部性修改

    (3)进程局部性修改

    2、cpu的亲和配置

     (1)具体设置

    3、事件处理模型优化

    4、设置work_connections连接数

    5、keepalive timeout会话保持时间

    6、GZIP压缩性能优化

    7、连接超时时间

    8、proxy超时设置

    buffer工作原理

    9、proxy_set_header

    10、高效传输模式

    11、fastcgi调优

    12、expires缓存调优

    13、访问限流 

    四、内核参数优化

    五、实战配置

    5.1、内核参数配置

    5.2、nginx全局配置

    5.3、负载均衡

    5.4、 server配置

    5.5、HTTPS配置(ssl配置)


    一、性能优化考虑点

            当我需要进行性能优化时,说明我们服务器无法满足日益增长的业务。性能优化是一个比较大的课题,需要从以下几个方面进行探讨。

            当前系统结构瓶颈

            了解业务模式

            性能和安全

    一、当前系统结构瓶颈

            首先需要了解的是当前系统瓶颈,用的是什么,跑的什么业务。里面的服务是什么样子,每个服务最大支持多少并发。比如针对Nginx而言,我们处理静态资源最高的瓶颈是多大。

            可以通过查看当前cpu负荷,内存使用率,进程使用率来做简单判断。还可以通过操作系统的一些工具来判断当前系统性能瓶颈,如分析对应日志,查看请求数量。

            也可以通过nginx vts模块来查看对应的来凝结数,总握手次数,总请求数。以对上线进行压力测试,来了解当前的系统的性能,并发数,做好性能评估。

    二、了解业务模式

            虽然我们是在做性能优化,但还是要熟悉业务,最终目的都是为了业务服务的。我们要了解每一个接口业务类型是什么样的业务,比如电子商务抢购模式,这种情况配是流量会很小,但是到了抢购时间,流量一下子就会猛涨。也要了解系统层级结构,每一层中间层做的是代理还是动静分离,还是后台进行直接服务。需要我们对业务接入层和系统层次要有一个梳理。

    三、系统与Nginx性能优化

            大家对相关的系统瓶颈及现状有了一定的了解之后,就可以根据邮箱性能方面做一个全体的优化。

            网络(网络流量、是否有丢包、网络的稳定性都会邮箱用户请求)

            系统(系统负载、饱和、内存使用率、系统的稳定性、硬盘磁盘是否损坏)

            服务(连接优化、内核性能优化、http服务请求优化都可以在nginx中根据业务来进行设置)

            程序(接口性能、处理请求速度、每个程序的执行效率)

            数据库、底层服务

    上面列举出来每一级都会有关联,也会邮箱整体性能,这里主要关注的是Nginx服务这一层。

    1、文件句柄

            linux/unix,一切皆文件,每一次用户发起请求就会生成一个文件句柄,文件句柄可以理解为就是一个索引,所有文件句柄就会随着请求量的增多,而进程调用的频率增加,文件句柄的产生就会越多,系统对文件句柄默认的限制是1024个,对于nginx来说非常小了,需要改大一点

    ulimit -n #可以查看系统设置的最大文件句柄

    (1)设置方式

            系统全局性修改

            用户局部性修改

            进程局部性修改

    (2)系统全局性修改和用户局部性修改

    vim /etc/security/limits.conf

    1. soft:软控制,到达设定值后,操作系统不会采取措施,只是发提醒
    2. hard:硬控制,到达设定值后,操作系统会采取机制对当前进行进行限制,这个时候请求就会受到影响
    3. root:这里代表root用户(系统全局性修改)
    4. *:代表全局,即所有用户都受此限制(用户局部性修改)
    5. nofile:指限制的是文件数的配置项。后面的数字即设定的值,一般设置10000左右

    尤其在企业新装的系统,这个地方应该根据实际情况进行设置,可以设置全局的,也可以设置用户级别的。

    su  #刷新以下环境

    ulimit -n   #再次查看系统最大文件句柄

     

     这里就改为了,我们对root用户设置的最大文件句柄65535

    (3)进程局部性修改

    vim /usr/local/nginx/conf/nginx.conf

    每个进程的最大文件打开数,所以最好与ulimit -n的值保持一致。

     重启一下服务

    2、cpu的亲和配置

    cpu的亲和能偶使nginx对于不同的work工作进程绑定到不同的cpu上面去。就能够减少在work间不断切换cpu,把进程通常不会在处理器之间频繁迁移,进程迁移的频率小,来减少性能损耗。

     (1)具体设置

    Nginx允许工作进程个数一般设置CPU的核心或者核心数*2.如果不了解cpu核数,可以使用top后按1看出来,也可以查看/proc/cpuinfo文件

    cat /proc/cpuinfo | grep ^processor | wc -l  #查看cpu核数

    lscpu | grep "CPU(s)"  #另一种查看cpu核数的方式

     

    这里我是4核

    随后进入nginx配置文件进行修改。需要知道的就是nginx 1.9版本之后,就帮我们自动绑定了cpu;

    所以我们只需要打开cpu亲和就行

    vim /usr/local/nginx/conf/nginx.conf

    1. user nginx;
    2. worker_processes 4;
    3. worker_cpu_affinity auto;
    4. 当然也可以改为 worker_cpu_affinity 0001 0010 0100 1000;
    5. worker_rlimit_nofile 65535;

     worker_rlimit_nofile更改worker进程的最大打开文件数限制。如果没设置的话,这个值为操作系统的限制。设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件,使用把这个值设高,这样nginx就不会由 “too many open files”问题了。

    重启一下nginx,查看一下nginx worker进程绑定对应的cpu

    ps -eo pid,args,psr | grep -v grep | grep nginx

     这样就能看到nginx的子进程都绑定到了哪些cpu核上

    3、事件处理模型优化

    nginx的连接处理机制在于不同的操作系统会采用不同的I/O模型,Linux下,nginx使用epoll的I/O多路复用模型,在freebsd(类unix操作系统)使用kqueue的I/O多路复用模型,在Solaris(unix系统的一个重要分支操作系统)使用/dev/pool方式的I/O多路复用模型,在windows使用的icop等等。要根据系统类型不同选择不同的事物处理模型,我们使用的是centos,因此讲nginx的事件处理模型调整为epoll。

    进入配置文件再进行修改

    1. events {
    2. worker_connections 10240;
    3. multi_accept on;
    4. use epoll;
    5. }

            multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on,设置为on后,多个worker按串行 方式来处理连接,也就是一个连接只有一个worker被唤醒,其他的处于休眠状态,设置为off后,多个worker按并行 方式来处理连接,也就是一个连接会唤醒所有的worker,直到连接分配完毕,没有取得连接的继续休眠。当你的服 务器连接数不多时,开启这个参数会让负载有一定的降低,但是当服务器的吞吐量很大时,为了效率,可以关闭这个参数。

    4、设置work_connections连接数

     work_connections表示每个worker(子进程)可以创建多少个连接,默认1024,最大是65535.

    这里我自己改为10240(这个参数与服务器性能相关)

    worker_connections  10240;
    

    5、keepalive timeout会话保持时间

    1. keepalive_timeout 65;
    2. keepalive其他的一些配置
    3. keepalive:像上游服务器的保留连接数
    4. keepalive_disable:是指把某些浏览器禁用掉
    5. keepalive_requests:这个表示当我们建立一个可复用长连接,在当前这一个连接里可以并发接收多少个请求,默认1000个
    6. send_timeout:在向客户端发送数据时,建立好连接后,超过两次活动时间(服务器很长时间没有返回数据)那么就会将这个连接关掉
    7. keepalive_time:一个tcp连接的总时长,超过这个时间要再请求连接一下

          这里先解释一下什么是keepalive,keepalive就是建立一下长连接,这个timeout就是,当浏览器建立一个连接之后,这个连接最长能存在多少事件不给他关闭,这个65也不是说建立65s连接后就直接关闭,而是一个活跃事件,就是第一次请求和下一次请求都会刷新这个65s,再65s内没有再请求数据才会真的关闭这个连接,所以这个事件也不应该太长,60左右也差不多了。

    6、GZIP压缩性能优化

    1. gzip on; #表示开启压缩功能
    2. gzip_min_length 1k; #表示允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值为0,表示不管页面多大都进行压缩,设置建议设大于1k。如果小于1k可能会越压越大。
    3. gzip_buffers 4 32k; #压缩缓存区大小
    4. gzip_http_version 1.1; #压缩版本
    5. gzip_comp_level 6; #压缩比率,一般选择4-6,为了性能gzip_typs text/css text/xml application/javascript; #指>定压缩的类型 gzip_vary on; #vary header支持;
    6. gzip_types text/plain text/css text/javascript application/json application/javascript
    7. gzip_vary on :varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据。

     

    1.gzip_min_length 1k :设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。

    2.gzip_buffers 4 32k :压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。

    3.gzip_http_version 1.1 :压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可。

    4.gzip_comp_level 6 :压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。

    5.gzip_types text/css text/xml application/javascript :用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩)

        压缩类型,匹配MIME型进行压缩;

    7、连接超时时间

    其目的是保护服务器资源,cpu,内存没控制连接数,因为建立连接也是需要消耗资源的。

    1. keepalive_timeout 60;
    2. tcp_nodelay on;
    3. client_header_buffer_size 4k;
    4. open_file_cache max=102400 inactive=20s;
    5. open_file_cache_valid 30s;
    6. open_file_cache_min_uses 1;
    7. client_header_timeout 15;
    8. client_body_timeout 15;
    9. reset_timedout_connection on;
    10. send_timeout 15;
    11. server_tokens off;
    12. client_max_body_size 10m;
    • keepalived_timeout :客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接。
    • tcp_nodelay:也是防止网络阻塞,不过要包涵在keepalived参数才有效。
    • client_header_buffer_size 4k:客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过 1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。
    • open_file_cache max=102400 inactive=20s :这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。
    • open_file_cache_valid 30s:这个是指多长时间检查一次缓存的有效信息。
    • open_file_cache_min_uses 1 :open_file_cache指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。
    • client_header_timeout : 设置请求头的超时时间。我们也可以把这个设置低些,如果超过这个时间没有发送任何数据,nginx将返回request time out的错误。
    • client_body_timeout设置请求体的超时时间。我们也可以把这个设置低些,超过这个时间没有发送任何数据,和上面一样的错误提示。
    • reset_timeout_connection :告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。
    • send_timeout :响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接。
    • server_tokens :并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。
    • client_max_body_size:上传文件大小限制。

    8、proxy超时设置

    1. proxy_connect_timeout 90; #后端服务器连接的超时时间,发起握手等候响应超时时间
    2. proxy_send_timeout 90; #后端服务器数据回传时间,就是在规定时间内后端服务器必须传完所有的数据
    3. proxy_read_timeout 90; #连接成功后,等候后端服务器响应时间,其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间,页面等待服务器响应时间)
    4. proxy_buffers 4 32k; #4是数量 32k是大小 该指令设置缓存区的大小和数量,从被代理的后端服务器取得的第一部分响应内容,会放置到这里,默认情况下,一个缓存区的大小等于内存页面大小,可能是4k也可能是8k取决于平台
    5. proxy_busy_buffers_size 64k; #nginx在收到服务器数据后,会分配一部分缓冲区来用于向客户端发送数据,这个缓存区大小由proxy_busy_buffers_size决定的。大小通常是proxy_buffers单位大小的两倍,官网默认是8k/16k。

    buffer工作原理

    1.所有的proxy buffer参数都是作用到每一个请求的。每一个全球有会按照参数的配置获得自己的buffer。proxy buffer不是global(全局配置),而是per request(在请求前执行的操作(如时间戳、签名))的

    2、proxy_buffering是为了开启response buffering of the proxied server(反向代理服务器响应数据的缓存),开启后proxy_buffers和proxy_busy_buffers_size参数才会起作用

    3、无论peoxy_buffer是否开启,proxy_buffer_size都是工作的,proxy_buffer_size所设置的buffer_size的作用是用来存储upstream端response的header。

    4、在proxy_buffering 开启的情况下,Nginx将会尽可能的读取所有的upstream端传输的数据到buffer,直到proxy_buffers设置的所有buffer们被写满或者数据被读取完(EOF)。此时nginx开始向客户端传输数据,会同时传输这一整串buffer们。同时如果response的内容很大的话,Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。如果busy的buffer传输完了会从temp_file里面接着读数据,直到传输完毕。

    5、一旦proxy_buffers设置的buffer被写入,直到buffer里面的数据被完整的传输完(传输到客户端),这个buffer将会一直处在busy状态,我们不能对这个buffer进行任何别的操作。所有处在busy状态的buffer size加起来不能超过proxy_busy_buffers_size,所以proxy_busy_buffers_size是用来控制同时传输到客户端的buffer数量的。

    9、proxy_set_header

    proxy_set_header用来设定被代理服务器接收到的header信息。

    语法:proxy_set_header field value;
    field :为要更改的项目,也可以理解为变量的名字,比如host
    value :为变量的值
    如果不设置proxy_set_header,则默认host的值为proxy_pass后面跟的那个域名或者IP(一般写IP)

    proxy_set_header X-Real-IP $remote_addr;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    用来设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。

    实战配置

    1. server {
    2. ...
    3. location /http/ {
    4. proxy_pass http://http_backend;
    5. proxy_http_version 1.1; # 对于http协议应该指定为1.1
    6. proxy_set_header Connection ""; # 清除"connection"头字段 , Connection: keep-alive
    7. proxy_set_header Host $http_host; # 代理服务器匹配请求web01服务器的时候,默认加上Host头信息(域名)
    8. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 追加客户端ip地址以及全链路ip地址到web服务器记录日志
    9. proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    10. # 当Nginx虚拟服务池其中任意一台服务器返回错误码500,502,503,504等错误时,可以分配到下一台服务器程序继续处理,提高平台访问的成功率
    11. proxy_connect_timeout 60s; # nginx代理与后端服务器连接超时时间(代理连接超时)
    12. proxy_read_timeout 60s; # nginx代理等待后端服务器的响应时间(代理响应超时)
    13. proxy_send_timeout 60s; # 后端服务器数据回传给nginx代理超时时间(回传数据给代理超时)
    14. proxy_buffering on; # nginx会把后端返回的内容先放到缓冲区中,然后再返回给客户端,边收边传,不是全部接收再传给客户端
    15. proxy_buffers_size 4k; # 设置nginx代理保存用户头信息的缓存区大小
    16. proxy_buffers 8 8k; # 设置nginx代理缓冲区大小(8*8 = 64k)
    17. ...
    18. }
    19. }

           $proxy_host 自然是 proxy_pass后面跟着的host 比如一个请求 https://zhidao.baidu.com/question/22908463.html
           Request.ServerVariables("HTTP_HOST") 可以获得HTTP_HOST请求标题:zhidao.baidu.com

          $http_host始终等于HTTP_HOST请求标题

          $host等于$http_host,小写并且没有端口号(如果存在),除非HTTP_HOST不存在或是空值。在这种情况下,$host等于server_name
          $proxy_add_x_forwarded_for  。从客户访问到到最后的后台服务所经理的所有节点的ip汇总221.221.1.100,10.30.30.109,...  

            nginx的自带变量 $remote_addr 代表客户端的IP

            $remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。

            $remote_addr 只能获取到与服务器本身直连的上层请求ip,所以设置$remote_addr一般都是设置第一个代理上面;但是问题是,有时候是通过cdn访问过来的,那么后面web服务器获取到的,永远都是cdn 的ip 而非真是用户ip,那么这个时候就要用到X-Forwarded-For 了,这个变量的意思,其实就像是链路反追踪,从客户的真实ip为起点,穿过多层级的proxy ,最终到达web 服务器,都会记录下来,所以在获取用户真实ip的时候,一般就可以设置成,proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 这样就能获取所有的代理ip 客户ip。 $proxy_add_x_forwarded_for变量包含客户端请求头中的X-Forwarded-For$remote_addr两部分,他们之间用逗号分开。

    10、高效传输模式

    1. sendfile on; #开启高效文件传输模式。
    2. tcp_nopush on;#需要在sendfile开启模式才有效,防止网络阻塞,级级的减少网络报文段的数量。将响应头和正文的开始部分一起发送,而不是一个接一个的发送(也就是说数据包不会马上传出等到数据包最大时一次性传)
    3. tcp_nodelay on; #只要有数据包产生,不管大小多少,就尽快传输

    11、fastcgi调优

    1. fastcgi_connect_timeout 600;
    2. fastcgi_send_timeout 600;
    3. fastcgi_read_timeout 600;
    4. fastcgi_buffer_size 64k;
    5. fastcgi_buffers 4 64k;
    6. fastcgi_busy_buffers_size 128k;
    7. fastcgi_temp_file_write_size 128k;
    8. fastcgi_temp_path/usr/local/nginx1.22/nginx_tmp;
    9. fastcgi_intercept_errors on;
    10. fastcgi_cache_path/usr/local/nginx1.22/fastcgi_cache levels=1:2
    11. keys_zone=cache_fastcgi:128minactive=1d max_size=10g;
    • fastcgi_connect_timeout 600 :指定连接到后端FastCGI的超时时间。
    • fastcgi_send_timeout 600 :向FastCGI传送请求的超时时间。
    • fastcgi_read_timeout 600 :指定接收FastCGI应答的超时时间。
    • fastcgi_buffer_size 64k :指定读取FastCGI应答第一部分需要用多大的缓冲区,默认的缓冲区大小为。fastcgi_buffers指令中的每块大小,可以将这个值设置更小。
    • fastcgi_buffers 4 64k :指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存,如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp_path指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于磁盘。一般这个值应该为站点中php脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“8 32K”、“4 64k”等。
    • fastcgi_busy_buffers_size 128k :建议设置为fastcgi_buffers的两倍,繁忙时候的buffer。
    • fastcgi_temp_file_write_size 128k :在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,该数值设置小时若负载上来时可能报502BadGateway。
    • fastcgi_temp_path :缓存临时目录。
    • fastcgi_intercept_errors on :这个指令指定是否传递4xx和5xx错误信息到客户端,或者允许nginx使用error_page处理错误信息。注:静态文件不存在会返回404页面,但是php页面则返回空白页!
    • fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cachelevels=1:2
      keys_zone=cache_fastcgi:128minactive=1d max_size=10g :fastcgi_cache缓存目录,可以设置目录层级,比如1:2会生成16*256个子目录,cache_fastcgi是这个缓存空间的名字,cache是用多少内存(这样热门的内容nginx直接放内存,提高访问速度),inactive表示默认失效时间,如果缓存数据在失效时间内没有被访问,将被删除,max_size表示最多用多少硬盘空间。
    • fastcgi_cache cache_fastcgi :#表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502的错误放生。cache_fastcgi为proxy_cache_path指令创建的缓存区名称。
    • fastcgi_cache_valid 200 302 1h :#用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一小时,要和fastcgi_cache配合使用。
    • fastcgi_cache_valid 301 1d :将301应答缓存一天。
    • fastcgi_cache_valid any 1m :将其他应答缓存为1分钟。
    • fastcgi_cache_min_uses 1 :该指令用于设置经过多少次请求的相同URL将被缓存。
    • fastcgi_cache_key http://h o s t hosthostrequest_uri :该指令用来设置web缓存的Key值,nginx根据Key值md5哈希存储.一般根据h o s t ( 域 名 ) 、 host(域名)、host(域名)、request_uri(请求的路径)等变量组合成proxy_cache_key 。
    • fastcgi_pass :指定FastCGI服务器监听端口与地址,可以是本机或者其它。

    总结:
    nginx的缓存功能有:proxy_cache / fastcgi_cache

    • proxy_cache的作用是缓存后端服务器的内容,可能是任何内容,包括静态的和动态。
    • fastcgi_cache的作用是缓存fastcgi生成的内容,很多情况是php生成的动态的内容。
    • proxy_cache缓存减少了nginx与后端通信的次数,节省了传输时间和后端宽带。
    • fastcgi_cache缓存减少了nginx与php的通信的次数,更减轻了php和数据库(mysql)的压力。

    12、expires缓存调优

            缓存,主要针对于图片,css,js等元素更改机会比较少的情况下使用,特别是图片,占用带宽大,我们完全可以设置图片在浏览器本地缓存365d,css,js,html可以缓存个10来天,这样用户第一次打开加载慢一点,第二次,就非常快了!缓存的时候,我们需要将需要缓存的拓展名列出来, Expires缓存配置在server字段里面。

    1. location ~* \.(ico|jpe?g|gif|png|bmp|swf|flv)$ {
    2. expires 30d; #过期时间为30天
    3. #log_not_found off;
    4. access_log off;
    5. }
    6. location ~* \.(js|css)$ {
    7. expires 7d;
    8. log_not_found off;
    9. access_log off;
    10. }

    注:log_not_found off;是否在error_log中记录不存在的错误。默认是。

    Expires:是缓存到期的时间

    13、访问限流 

            我们构建网站是为了让用户访问它们,我们希望用于合法访问。所以不得不采取一些措施限制滥用访问的用户。这种滥用指的是从同一IP每秒到服务器请求的连接数。因为这可能是在同一时间内,世界各地的多台机器上的爬虫机器人多次尝试爬取网站的内容。

    1. #限制用户连接数来预防DOS攻击
    2. limit_conn_zone $binary_remote_addr zone=perip:10m;
    3. limit_conn_zone $server_name zone=perserver:10m;
    4. #限制同一客户端ip最大并发连接数
    5. limit_conn perip 2;
    6. #限制同一server最大并发连接数
    7. limit_conn perserver 20;
    8. #限制下载速度,根据自身服务器带宽配置
    9. limit_rate 300k;

    四、内核参数优化

    1. vim /etc/sysctl.conf #进入这个文件修改
    2. sysctl -p #让修改的内核信息生效
    3. #################################################
    4. fs.file-max = 999999
    5. net.ipv4.ip_forward = 0
    6. net.ipv4.conf.default.rp_filter = 1
    7. net.ipv4.conf.default.accept_source_route = 0
    8. kernel.sysrq = 0
    9. kernel.core_uses_pid = 1
    10. net.ipv4.tcp_syncookies = 1
    11. kernel.msgmnb = 65536
    12. kernel.msgmax = 65536
    13. kernel.shmmax = 68719476736
    14. kernel.shmall = 4294967296
    15. net.ipv4.tcp_max_tw_buckets = 6000
    16. net.ipv4.tcp_sack = 1
    17. net.ipv4.tcp_window_scaling = 1
    18. net.ipv4.tcp_rmem = 10240 87380 12582912
    19. net.ipv4.tcp_wmem = 10240 87380 12582912
    20. net.core.wmem_default = 8388608
    21. net.core.rmem_default = 8388608
    22. net.core.rmem_max = 16777216
    23. net.core.wmem_max = 16777216
    24. net.core.netdev_max_backlog = 262144
    25. net.core.somaxconn = 40960
    26. net.ipv4.tcp_max_orphans = 3276800
    27. net.ipv4.tcp_max_syn_backlog = 262144
    28. net.ipv4.tcp_timestamps = 0
    29. net.ipv4.tcp_synack_retries = 1
    30. net.ipv4.tcp_syn_retries = 1
    31. net.ipv4.tcp_tw_recycle = 1
    32. net.ipv4.tcp_tw_reuse = 1
    33. net.ipv4.tcp_mem = 94500000 915000000 927000000
    34. net.ipv4.tcp_fin_timeout = 1
    35. net.ipv4.tcp_keepalive_time = 30
    36. net.ipv4.ip_local_port_range = 1024 65000
    • fs.file-max = 999999:这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直线限制最大并发连接数,需根据实际情况配置。
    • net.ipv4.tcp_max_tw_buckets = 6000 :这个参数表示操作系统允许TIME_WAIT套接字数量的最大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。注:主动关闭连接的服务端会产生TIME_WAIT状态的连接
    • net.ipv4.ip_local_port_range = 1024 65000 :允许系统打开的端口范围。
    • net.ipv4.tcp_tw_recycle = 1 :启用timewait快速回收。
    • net.ipv4.tcp_tw_reuse = 1 :开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接。
    • net.ipv4.tcp_keepalive_time = 30:这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置的小一些,可以更快地清理无效的连接。
    • net.ipv4.tcp_syncookies = 1 :开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。
    • net.core.somaxconn = 40960 :web 应用中 listen 函数的 backlog 默认会给我们内核参数的。
    • net.core.somaxconn :限制到128,而nginx定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。注:对于一个TCP连接,Server与Client需要通过三次握手来建立网络连接.当三次握手成功后,我们可以看到端口的状态由LISTEN转变为ESTABLISHED,接着这条链路上就可以开始传送数据了.每一个处于监听(Listen)状态的端口,都有自己的监听队列.监听队列的长度与如somaxconn参数和使用该端口的程序中listen()函数有关。somaxconn定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。
    • net.core.netdev_max_backlog = 262144 :每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
    • net.ipv4.tcp_max_syn_backlog = 262144 :这个参数标示TCP三次握手建立阶段接受SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求。
    • net.ipv4.tcp_rmem = 10240 87380 12582912 :这个参数定义了TCP接受缓存(用于TCP接受滑动窗口)的最小值、默认值、最大值。
    • net.ipv4.tcp_wmem = 10240 87380 12582912:这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小值、默认值、最大值。
    • 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攻击。

    五、实战配置

    5.1、内核参数配置

    1. #如果想把timewait降下了就要把tcp_max_tw_buckets值减小,默认是180000
    2. net.ipv4.tcp_max_tw_buckets = 5000
    3. #开启重用功能,允许将TIME-WAIT状态的sockets重新用于新的TCP连接
    4. net.ipv4.tcp_tw_reuse = 1
    5. #系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击
    6. net.ipv4.tcp_max_orphans = 262144
    7. #当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时。我们可以调短时间跨度
    8. net.ipv4.tcp_keepalive_time = 30

    5.2、nginx全局配置

    1. worker_processes 1;
    2. pid /var/run/nginx.pid;
    3. events {
    4. worker_connections 2048;
    5. multi_accept on;
    6. use epoll;
    7. }
    8. http {
    9. include /etc/nginx/mime.types;
    10. default_type application/octet-stream;
    11. log_format main '{"@timestamp":"$time_iso8601",'
    12. '"host":"$server_addr",'
    13. '"clientip":"$remote_addr",'
    14. '"size":$body_bytes_sent,'
    15. '"responsetime":$request_time,'
    16. '"upstreamtime":"$upstream_response_time",'
    17. '"upstreamhost":"$upstream_addr",'
    18. '"http_host":"$host",'
    19. '"url":"$uri",'
    20. '"xff":"$http_x_forwarded_for",'
    21. '"referer":"$http_referer",'
    22. '"agent":"$http_user_agent",'
    23. '"status":"$status"}';
    24. sendfile on;
    25. tcp_nopush on;
    26. tcp_nodelay on;
    27. server_names_hash_bucket_size 128;
    28. server_names_hash_max_size 512;
    29. keepalive_timeout 65;
    30. client_header_timeout 15s;
    31. client_body_timeout 15s;
    32. send_timeout 60s;
    33. limit_conn_zone $binary_remote_addr zone=perip:10m;
    34. limit_conn_zone $server_name zone=perserver:10m;
    35. limit_conn perip 2;
    36. limit_conn perserver 20;
    37. limit_rate 300k;
    38. proxy_cache_path /data/nginx-cache levels=1:2 keys_zone=nginx-cache:20m max_size=50g inactive=168h;
    39. client_body_buffer_size 512k;
    40. client_header_buffer_size 4k;
    41. client_max_body_size 512k;
    42. large_client_header_buffers 2 8k;
    43. proxy_connect_timeout 5s;
    44. proxy_send_timeout 120s;
    45. proxy_read_timeout 120s;
    46. proxy_buffer_size 16k;
    47. proxy_buffers 4 64k;
    48. proxy_busy_buffers_size 128k;
    49. proxy_temp_file_write_size 128k;
    50. proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;
    51. gzip on;
    52. gzip_min_length 1k;
    53. gzip_buffers 4 16k;
    54. gzip_http_version 1.1;
    55. gzip_comp_level 4;
    56. gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    57. gzip_vary on;
    58. gzip_disable "MSIE [1-6].";
    59. include /etc/nginx/conf.d/*.conf;
    60. }

    5.3、负载均衡

    1. upstream ygoapi{
    2. server ip:port fail_timeout=5 max_fails=3;
    3. server ip:port fail_timeout=5 max_fails=3;
    4. ip_hash; #负载均衡策略
    5. }

    5.4、 server配置

    1. #隐藏版本信息
    2. server_tokens off;
    3. server {
    4. listen 80;
    5. server_name www.ygoclub.com;
    6. charset utf-8;
    7. #重定向HTTP请求到HTTPS
    8. return 301 https://$server_name$request_uri;
    9. }

    5.5、HTTPS配置

    这里主要是配置ssl证书

    在nginx服务的目录下创建cert

    1. server {
    2. listen 443;
    3. server_name 域名;
    4. ssl on;
    5. root /xxx/xxx/html; // 前台文件存放文件夹,一般使用 Nginx 初始化的文件夹,当然也可以自己修改
    6. index index.html;// 上面配置的文件夹里面的index.html
    7. ssl_certificate /路径/证书名称.pem;
    8. ssl_certificate_key /路径/证书名称.key;
    9. ssl_session_timeout 5m;
    10. # SSL协议配置
    11. ssl_protocols SSLv2 SSLv3 TLSv1.2; #表示使用TLS类型协议
    12. ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #表示使用加密套件的类型
    13. ssl_prefer_server_ciphers on;
    14. location / {
    15. proxy_redirect off;
    16. proxy_set_header Host $host;
    17. proxy_set_header X-Real-IP $remote_addr;
    18. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    19. proxy_pass http://127.0.0.1:8080;
    20. }
    21. }
    22. }
    23. server {
    24. listen 80;
    25. server_name your-domain.com;// 你的域名
    26. rewrite ^(.*)$ https://$host:443$1 permanent;// 把http的域名请求转成https且转发到443端口
    27. }
  • 相关阅读:
    瑞吉外卖学习笔记4
    centos编译安装opencv,生成opencv-2413.jar
    为什么老外会说有些业务员的询盘回复不是他想要的?
    用Prophet在Python中进行时间序列预测
    【数据结构】时间复杂度和空间复杂度
    io流笔记
    已解决json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    仿制药的未来商机--个人研发的体会
    基于.NetCore开发博客项目 StarBlog - (20) 图片显示优化
    Windows11+Ubuntu 3系统如何安全地删掉最后一个Ubuntu系统?
  • 原文地址:https://blog.csdn.net/qq_57377057/article/details/126568841