nginx配置之性能篇

在高并发连接的情况下,Nginx是Apache服务器不错的替代品。Nginx同时也可以作为7层负载均衡服务器来使用。根据相关的测试结果,Nginx 0.7.14 + PHP 5.2.6 (FastCGI) 可以承受3万以上的并发连接数,相当于同等环境下Apache的10倍。

通常,4GB内存的服务器+Apache(prefork模式)一般只能处理3000个并发连接,因为它们将占用3GB以上的内存,还得为系统预留1GB的内存。

[TOC]

常规优化

events 优化

  • worker_connections 配置合理的最大连接数
  • use epoll; 为 Linux 下多路复用IO接口select/poll的增强版本,它能显著减少程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
events {
    use epoll;                  # 事件处理模型优化,可以大大提高nginx性能
    worker_connections 30000;   # 指定单个后台worker process进程的最大并发连接数,默认512
    multi_accept on;            # 使nginx能尽快接收尽可能多的请求,减少客户端的连接初始化时间.
}

TCP 优化

  • Nginx 关于 TCP 的优化基本都是修改系统内核提供的配置项,简单介绍如下:
http {
    sendfile on;            # 允许调用sendfile函数来高效传输静态文件,对于普通应用,必须设为on
    tcp_nopush on;          # 设置nginx在一个数据包里发送所有头文件,而不一个接一个的发送,可减少网络报文段的数量,只有在启用sendfile之后才生效
    tcp_nodelay on;         # 启用后会禁用nagle算法,设置nginx不要缓存数据,而是一段一段的尽快发送

    keepalive_timeout 60;   # 指定服务端为每个TCP连接最多可以保持多长时间,默认75秒
}

启用 gzip 压缩

  • 通常,对于文本文件,在服务端发送响应之前进行 GZip 压缩,可减小到原来的 1/4 - 1/3
  • 启用gzip压缩,使得返回客户端的内容更简短,传输更快,但启用压缩会消耗CPU资源,如果消耗CPU过高,可以考虑禁用压缩
  • 通常只压缩大文件,避免压缩那些压缩效果不好的文件,例如图片、可执行文件等二进制文件
http {
    gzip on;                # 启用gzip压缩
    gzip_static on;         # 告诉nginx在压缩资源之前,先查找是否有预先gzip处理过的资源,如果有就不用再压缩了
    gzip_vary on;           # 开启自动输出"Vary: Accept-Encoding"响应头字段,可解决某些缓存服务问题
    gzip_comp_level 6;      # 数据的压缩等级,1-9,9是最慢但是压缩比最大的,默认1
    gzip_buffers 16 8k;     # 压缩缓冲区个数和大小,默认32 4k|16 8k;
    gzip_proxied any;       # 允许或者禁止压缩基于请求和响应的响应流,设置为any意味着将会压缩所有的请求.
    gzip_min_length 1k;     # 对数据启用压缩的最少字节数.如果一个请求小于1024字节,最好不要压缩它,因为压缩这些小的数据会降低处理此请求的所有进程的速度.
    gzip_disable "msie6";   # 为指定的客户端禁用gzip功能,这里禁止IE6或者更低版本.或 gzip_disable "MSIE [1-6]\.";
    gzip_http_version 1.1;  # 针对 HTTP/1.1 及以上的请求开启 GZip
    gzip_types
        text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
        text/javascript application/javascript application/x-javascript
        text/x-json application/json application/x-web-app-manifest+json
        text/css text/plain text/x-component
        font/opentype application/x-font-ttf application/vnd.ms-fontobject
        image/x-icon;       # 需要压缩的数据类型
}

开启客户端缓存

  • 客户端缓存:最简单的办法是将所有的图片、js等静态内容设置一个固定的时间长度
http {
    #.其他省略...
    server {
        #.其他省略...
        location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
            access_log        off;
            log_not_found     off;
            expires           30d;        # 过期时间设置为30天,若静态文件不常更新则设大一点,若频繁更新则设小一点
        }
    }
}

设置超时时间

  • 设置timeout可防御DOS攻击
http {
    keepalive_timeout 60;           # TCP长连接存活时间,默认75秒
    client_header_timeout 10;       # 设置请求头header的超时时间
    client_body_timeout 10;         # 设置请求体body的超时时间
    send_timeout 600;               # 指定客户端的响应超时时间
}

HTTPS 优化

  • 启用 HTTPS 并正确配置了证书,意味着数据传输过程中无法被第三者解密或修改
http {
    #.其他省略...
    server {
        listen 443 ssl;
        server_name xxx.example.com;

        root /data/nginx/www/xxx.example.com;
        index index.html index.htm;

        ssl_certificate     /data/nginx/ssl/xxx.example.com.pem;
        ssl_certificate_key /data/nginx/ssl/xxx.example.com.key;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
    }
}

CPU 配置

  • 设置CPU亲和性,将worker进程绑定在特定CPU内核上,减小进程切换内核的开销。
vi ./conf/nginx.conf

#.以8核为例
worker_processes 8;      # 指定nginx提供web服务时的worder进程数,默认1
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;


# 注:cpumask通常设置方法
# 2核是01 10
# 4核是0001 0010 0100 1000
# 8核是00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000

配置worker进程最大打开文件数

  • 配置 nginx worker 进程最大打开文件数,相当于系统 ulimit -HSn
  • 该参数不是越大越好,最好设为服务器承受的极限点
worker_rlimit_nofile 65535;     # 指定单个工作进程可用文件描述符最大数量,建议等于ulimit -n,以避免"too many open files"问题

部署监控

  • 修改 nginx.conf 添加 nginx-status 监控
http {
    #.其他省略...
    server {
        #.其他省略...
        location /nginx-status {
            allow 127.0.0.1;
            deny all;
            stub_status on;
            access_log off;
        }
    }
}
  • 通过curl统计当前连接数
curl http://127.0.0.1:9002/nginx-status

进阶篇

优化 linux 内核

  • 修改 /etc/sysctl.conf 配置如下参数,然后 /sbin/sysctl -p /etc/sysctl.conf 使配置立即生效
net.ipv4.tcp_syncookies = 1                     # 开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认0
net.ipv4.tcp_tw_reuse = 1                       # 开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接,默认0
net.ipv4.tcp_tw_recycle = 1                     # 启用timewait快速回收,NAT环境建议设0禁用,linux4.12(centos7.9默认内核3.10.0)之后已废弃,默认0
net.ipv4.tcp_timestamps = 1                     # 只有该参数启用,tcp_tw_reuse和tcp_tw_recycle开启才能生效,默认1
net.ipv4.tcp_fin_timeout = 1                    # 当服务器主动关闭连接时,socket保持在FIN-WAIT-2状态的最大时间,默认60秒
net.ipv4.tcp_keepalive_time = 300               # 当keepalive启用时,TCP发送keepalive消息的频度,默认2小时
net.ipv4.tcp_max_tw_buckets = 5000              # 内核持有的状态为TIME_WAIT的最大数量,超出的TIME_WAIT连接会被立即销毁并打印警告,默认180000
net.ipv4.tcp_max_syn_backlog = 8192             # 调整SYN队列的长度,以容纳更多等待连接的网络连接数,默认1024
net.ipv4.ip_local_port_range = 1024 65535       # 允许系统打开的端口范围,默认32768到60999
net.core.somaxconn = 8192                       # web应用中listen函数的backlog,默认128
net.core.netdev_max_backlog = 8192              # 网卡接收数据包的速率比内核处理的速率快时,允许送到队列的数据包的最大数目

需要注意如下几点

  • 关于 net.ipv4.tcp_tw_recycle,NAT环境建议设0禁用,且linux4.12(centos7.9默认内核3.10.0)之后已废弃

优化 fastcgi

  • 优化fastcgi参数可以解决 nginx反向代理遇到的 504 Bad Gateway 错误
http {
    fastcgi_connect_timeout 300;             # 连接FastCGI超时秒数
    fastcgi_send_timeout 300;                # 向FastCGI传送请求超时秒数
    fastcgi_read_timeout 300;                # 接收FastCGI应答超时秒数
    fastcgi_buffer_size 64k;                 # 读取FastCGI应答头的缓冲大小,默认4k
    fastcgi_buffers 4 64k;                   # 读取FastCGI应答缓冲区个数和大小,默认4k
    fastcgi_busy_buffers_size 128k;          # 默认fastcgi_buffers的两倍
    fastcgi_temp_file_write_size 128k;      # 在写入fastcgi_temp_path 时将用多大的数据块,默认fastcgi_buffers的两倍
}

优化 php-fpm 参数

  • 修改 /etc/php-fpm.conf 中如下几个参数:
listen = 127.0.0.1:9000
pm = dynamic                        # php-fpm进程池开启进程的方式:static或dynamic
pm.max_children = 50                # 静态方式下开启的php-fpm进程数量,在动态方式下它限定php-fpm的最大进程数
pm.start_servers = 5                # 动态方式下的起始php-fpm进程数量
pm.min_spare_servers = 5            # 动态方式空闲状态下的最小php-fpm进程数量
pm.max_spare_servers = 100          # 动态方式空闲状态下的最大php-fpm进程数量
pm.max_requests = 10240             # 最大处理请求数,指定php-fpm的worker进程在处理多少个请求后就终止掉,避免第三方库造成的内存泄露,默认0
  • php-fpm进程池开启进程有两种方式,一种是static,直接开启指定数量的php-fpm进程,不再增加或者减少;
  • 另一种则是dynamic,开始时开启一定数量的php-fpm进程,当请求量变大时,动态的增加php-fpm进程数到上限,当空闲时自动释放空闲的进程数到一个下限。
  • 如果dm设置为 static 则只有 pm.max_children 这个参数生效,系统会开启参数设置数量的php-fpm进程
  • 如果dm设置为 dynamic 则4个参数都生效,系统会在php-fpm运行开始时启动 pm.start_servers 个php-fpm进程,然后根据系统的需求动态在 pm.min_spare_serverspm.max_spare_servers 之间调整php-fpm进程数
  • 通常,max_children 必须大于 max_spare_serversstart_servers 必须大于 min_spare_servers

优化 php 脚本超时时间

为了保证生产环境的安全,建议同时设置 max_execution_timerequest_terminate_timeout 参数值:

  • 修改 php.inimax_execution_time = 60
  • 修改 /etc/php-fpm.confrequest_terminate_timeout = 60
  • 执行 systemctl restart php-fpm 重启fpm进程以生效

优化 ulimit

  • 设置 ulimit 系统最大打开的文件数量,注意执行 ulimit -n临时生效
ulimit -SHn 65535
cat /etc/rc.local | grep ulimit || echo "ulimit -HSn 65535" >> /etc/rc.local
  • 永久生效:修改 /etc/security/limits.conf 文件,在文件末尾添加如下4行(其中 * 代表针对所有用户,noproc 代表最大进程数,nofile 代表最大文件打开数
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535

负载均衡

服务器负载均衡设备选型:

  • 硬件设备:F5、Citrix、Redware、A10
  • 软件:LVS、Nginx、Haproxy、zen loadbalance
Copyright © www.sqlfans.cn 2023 All Right Reserved更新时间: 2023-06-12 09:56:51

results matching ""

    No results matching ""