• 解除/配置 linux/nginx 的 tcp 连接(nginx配置文件日常配置推荐)


    nginx 文档 参数介绍:

    http://shouce.jb51.net/nginx-doc/Text/3.1_httpcore.html

    nginx 优化

    由于业务场景需要,近期将生产环境由阿里云的 SLB 更换为自建 nginx,之前在测试环境使用了一段时间一直没有问题,但是上周上到生产后出现了一系列问题,因此对 nginx 做了一些优化,记录下以备以后需要。

    高并发优化

    生产环境相对于测试环境访问量多了很多,并发量大的时候会出现部分请求 502 的情况,因此对高并发进行了一点优化,主要分两方面,一方面是系统层面,一方面是 nginx 层面。

    系统内核层面

    文件句柄限制
    在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是“Socket/File:Can’t open so many files”。
    
    这时你需要明白操作系统对可以打开的最大文件数的限制。
    
    进程限制
    
    执行 ulimit -n 输出 1024,说明对于一个进程而言最多只能打开1024个文件,所以你要采用此默认配置最多也就可以并发上千个TCP连接。
    
    临时修改:ulimit -n 1000000,但是这种临时修改只对当前登录用户目前的使用环境有效,系统重启或用户退出后就会失效。
    
    重启后失效的修改(不过我在CentOS 6.5下测试,重启后未发现失效):编辑 /etc/security/limits.conf 文件, 修改后内容为
    
    * soft nofile 102400
    * hard nofile 102400

    修改/etc/sysctl.conf内核参数。

    fs.file-max = 999999
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_keepalive_time = 15
    net.ipv4.tcp_fin_timeout = 15
    net.ipv4.tcp_max_tw_buckets = 5000
    net.core.netdev_max_backlog = 262144
    net.ipv4.tcp_max_orphans = 262144
    net.ipv4.tcp_tw_reuse = 1

    使配置生效

    sysctl -p
     

    参数说明:

    • fs.file-max:999999

      这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这 个参数直接限制最大并发连接数,需根据实际情况配置。

    • net.ipv4.tcp_tw_reuse:

      这个参数设置为1,表示允许将TIME-WAIT状态的socket重新用于新的 TCP连接,这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接。

    • net.ipv4.tcp_keepalive_time:

      这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。 默认是2小时,若将其设置得小一些,可以更快地清理无效的连接。

    • net.ipv4.tcp_fin_timeout:

      这个参数表示当服务器主动关闭连接时,socket保持在FIN-WAIT-2状态的最大时间。

    • net.ipv4.tcp_max_tw_buckets:

      这个参数表示操作系统允许TIME_WAIT套接字数量的最大值, 如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为 180000,过多的TIME_WAIT套接字会使Web服务器变慢。

    • net.core.netdev_max_backlog = 262144

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

    • net.ipv4.tcp_max_orphans = 262144

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

    • net.ipv4.tcp_tw_reuse = 1

      表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭

    Nginx 配置方面

    • worker_processes 4

      nginx进程数,建议按照cpu数目来指定,一般跟cpu核数相同或为它的倍数。

    • worker_cpu_affinity 00000001 00000010 00000100 00001000 ;

      为每个进程分配cpu,上例中将4个进程分配到4个cpu,当然可以写多个,或者将一个进程分配到多个cpu。

    • worker_rlimit_nofile

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

    • use epoll;

      使用epoll的I/O模型,用这个模型来高效处理异步事件

    • worker_connections 65535;

      每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processesworker_connections。这个值太小的后果就是你的系统会报:too many open files 等错误,导致你的系统死掉。一般给到服务器后最好通过 ulimit 命令结合修改 /etc/security/limits.conf(增加 soft nofile = * hard nofile=)两个配置值,将其设置的更大些。

    • keepalive_timeout 30;

      http连接超时时间,默认是60s,功能是使客户端到服务器端的连接在设定的时间内持续有效,当出现对服务器的后继请求时,该功能避免了建立或者重新建立连接。切记这个参数也不能设置过大!否则会导致许多无效的http连接占据着nginx的连接数,终nginx崩溃!

    • 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时间内一次没被使用,它将被移除。

    • sendfile on;

      sendfile()可以在磁盘和TCP socket之间互相拷贝数据(或任意两个文件描述符)。Pre-sendfile是传送数据之前在用户空间申请数据缓冲区。之后用read()将数据从文件拷贝到这个缓冲区,write()将缓冲区数据写入网络。sendfile()是立即将数据从磁盘读到OS缓存。因为这种拷贝是在内核完成的,sendfile()要比组合read()和write()以及打开关闭丢弃缓冲更加有效(更多有关于sendfile)。

    • tcp_nopush on;

      告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送。就是说数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞。

    • tcp_nodelay on;

      告诉nginx不要缓存数据,而是一段一段的发送–当需要及时发送数据时,就应该给应用设置这个属性,这样发送一小块数据信息时就不能立即得到返回值。

    upstream 容错配置说明

    1. 判断节点失效状态
      Nginx默认判断失败节点状态以connect refuse和time out状态为准,不以HTTP错误状态进行判断失败,因为HTTP只要能返回状态说明该节点还可以正常连接,所以nginx判断其还是存活状态;除非添加了proxy_next_upstream指令设置对404、502、503、504、500和time out等错误进行转到备机处理,在next_upstream过程中,会对fails进行累加,如果备用机处理还是错误则直接返回错误信息(但404不进行记录到错误数,如果不配置错误状态也不对其进行错误状态记录),综述,nginx记录错误数量只记录timeout 、connect refuse、502、500、503、504这6种状态,timeout和connect refuse是永远被记录错误状态,而502、500、503、504只有在配置proxy_next_upstream后nginx才会记录这4种HTTP错误到fails中,当fails大于等于max_fails时,则该节点失效;
    2. nginx 处理节点失效和恢复的触发条件
      nginx可以通过设置max_fails(最大尝试失败次数)和fail_timeout(失效时间,在到达最大尝试失败次数后,在fail_timeout的时间范围内节点被置为失效,除非所有节点都失效,否则该时间内,节点不进行恢复)对节点失败的尝试次数和失效时间进行设置,当超过最大尝试次数或失效时间未超过配置失效时间,则nginx会对节点状会置为失效状态,nginx不对该后端进行连接,直到超过失效时间或者所有节点都失效后,该节点重新置为有效,重新探测

    3. 所有节点失效后nginx将重新恢复所有节点进行探测
      如果探测所有节点均失效,备机也为失效时,那么nginx会对所有节点恢复为有效,重新尝试探测有效节点,如果探测到有效节点则返回正确节点内容,如果还是全部错误,那么继续探测下去,当没有正确信息时,节点失效时默认返回状态为502,但是下次访问节点时会继续探测正确节点,直到找到正确的为止。

    4. 通过proxy_next_upstream实现容灾和重复处理问题
      ngx_http_proxy_module 模块中包括proxy_next_upstream指令
      语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off …;
      默认值: proxy_next_upstream error timeout; 上下文: http, server, location

    其中:
    error   表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误。
    timeout   表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时。
    invalid_header   表示后端服务器返回空响应或者非法响应头
    http_500   表示后端服务器返回的响应状态码为500
    http_502   表示后端服务器返回的响应状态码为502
    http_503   表示后端服务器返回的响应状态码为503
    http_504   表示后端服务器返回的响应状态码为504
    http_404   表示后端服务器返回的响应状态码为404
    off   表示停止将请求发送给下一台后端服务器
    

    常用 nginx 标准配置(仅供参考)

    user www-data;
    worker_processes 8; # 默认与cpu合数相同, 最多配置为双倍
    worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000; # 与上面线程数量一致, 如果改为4,请删除4 个
    error_log   /www/log/nginx_error.log   crit;
    pid         /usr/local/nginx/nginx.pid;
    worker_rlimit_nofile 65535;
    
    events
    {
       use epoll;
       worker_connections 65535;
    }
    
    http
    {
       include       mime.types;
       default_type   application/octet-stream;
    
       charset   utf-8;
    
       server_names_hash_bucket_size 128;
       client_header_buffer_size 2k;
       large_client_header_buffers 4 4k;
       client_max_body_size 8m;
    
       sendfile on;
       tcp_nopush     on;
    
       keepalive_timeout 60;
    
       fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2
                     keys_zone=TEST:10m
                     inactive=5m;
       fastcgi_connect_timeout 300;
       fastcgi_send_timeout 300;
       fastcgi_read_timeout 300;
       fastcgi_buffer_size 16k;
       fastcgi_buffers 16 16k;
       fastcgi_busy_buffers_size 16k;
       fastcgi_temp_file_write_size 16k;
       fastcgi_cache TEST;
       fastcgi_cache_valid 200 302 1h;
       fastcgi_cache_valid 301 1d;
       fastcgi_cache_valid any 1m;
       fastcgi_cache_min_uses 1;
       fastcgi_cache_use_stale error timeout invalid_header http_500; 
       open_file_cache max=204800 inactive=20s;
       open_file_cache_min_uses 1;
       open_file_cache_valid 30s; 
    
       tcp_nodelay on;
    
       gzip on;
       gzip_min_length   1k;
       gzip_buffers     4 16k;
       gzip_http_version 1.0;
       gzip_comp_level 2;
       gzip_types       text/plain application/x-javascript text/css application/xml;
       gzip_vary on;
    
     upstream  test {
            server 192.168.5.34:9083 max_fails=3  fail_timeout=5s;
            server 192.168.5.35:9083 max_fails=3  fail_timeout=5s;
            server 192.168.5.36:9083 max_fails=3  fail_timeout=5s;
        }
       server
       {
         listen       80;
         server_name   www.test.com;
         index index.php index.htm;
         root   /www/html/;
    
       location /
         {
            proxy_pass http://test;
                proxy_set_header   Host    $host;
                proxy_set_header   X-Real-IP   $remote_addr;
                proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
         }
         location /status
         {
             stub_status on;
         }
    
         location ~ .*\.(php|php5)?$
         {
             fastcgi_pass 127.0.0.1:9000;
             fastcgi_index index.php;
             include fcgi.conf;
         }
    
         location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
         {
           expires       30d;
         }
    
         log_format   access   '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" '
                   '"$http_user_agent" $http_x_forwarded_for';
         access_log   /www/log/access.log   access;
           }
    }

     参数详细介绍请看文档:

    http://shouce.jb51.net/nginx-doc/Text/3.1_httpcore.html

     
     
  • 相关阅读:
    php switch case的"bug"
    win7 安装redis服务
    linux 查看网卡以及开启网卡
    getSelection、range 对象属性,方法理解,解释
    关于window.getSelection
    富文本原理
    elasticsearch启动常见错误
    Linux 修改用户密码
    centos修改主机名的正确方法
    Dockerfile介绍
  • 原文地址:https://www.cnblogs.com/presleyren/p/15772096.html
Copyright © 2020-2023  润新知