Nginx-性能优化

前言

这篇关于 Nginx 的性能优化,是我查阅资料研究所成,并无用于实际生产环境,如若你想用于实践,请谨慎测试以后使用。javascript

Nginx 性能优化,主要是减小磁盘 iocss

  • 请求头、请求体、响应体都在缓冲区操做。
  • 文件信息的读取

减小网络 io。前端

  • gzip 压缩。前端资源也能够提早进行 gzip 压缩,这样请求的时候就不用再压缩了,减小对 cpu 的损耗。
  • 强缓存。减小对后端的静态资源的请求。

http 连接的尽快释放,减小请求的堆积。java

linux 内核优化。这部分主要是查阅资料加上本身的理解。内容来自 《深刻理解 Nginx 模块开发与架构设计》。node

调帐参数以后可使用 abjmeter 进行压测,根据实际效果来进行调优。linux

Nginx 必定要在安全的状况下作性能优化。否则 tcp 攻击就能给你服务器搞挂了,能用才是王道。安全访问第一,性能第二。nginx

调优以后,必定记得要作限流哦。web

下个系列准备写 Mysql 相关,已经在作准备了。sql

linux 内核优化

能够修改 /etc/sysctl.conf 来修改内核参数。这部分优化慎重json

  • 查看 tcp 相关系统参数
sysctl -a | grep 'net.ipv4.tcp' | grep -v grep
复制代码
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.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 32768 262144
net.ipv4.tcp_wmem = 4096 32768 262144
net.ipv4.tcp_max_orphans = 262144 
net.core.netdev_max_backlog = 262144
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
net.core.somaxconn = 262144 
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog=262144
复制代码

修改以后执行如下命令,使配置生效。

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.ipv4.ip_local_port_range:

    这个参数定义了在UDP和TCP链接中本地(不包括链接的远端) 端口的取值范围。

  • net.ipv4.tcp_rmem:

    这个参数定义了TCP接收缓存(用于TCP接收滑动窗口)的最小 值、默认值、最大值。

  • net.ipv4.tcp_wmem:

    这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小 值、默认值、最大值。

  • net.ipv4.tcp_max_orphans

    选项用于记录那些还没有收到客户端确认信息的链接请求的最大值。对于有128MB内存的系统而言,此参数的默认值是1024,对小内存的系统则是128。

  • net.core.netdev_max_backlog:

    当网卡接收数据包的速度大于内核处理的速度时,会有一个队列 保存这些数据包。这个参数表示该队列的最大值。

  • net.core.net.core.rmem_default:

    这个参数表示内核套接字接收缓存区默认的大小。

  • net.core.wmem_default:

    这个参数表示内核套接字发送缓存区默认的大小。

  • net.core.rmem_max:

    这个参数表示内核套接字接收缓存区的最大大小。

  • net.core.wmem_max:

    这个参数表示内核套接字发送缓存区的最大大小。

滑动窗口的大小与套接字缓存区会在必定程度上影响并发链接的数目。

每一个 TCP链接都会为维护TCP滑动窗口而消耗内存,这个窗口会根据服务器的处理速度收缩或扩 张。

参数wmem_max的设置,须要平衡物理内存的总大小、Nginx并发处理的最大链接数量 (由nginx.conf中的worker_processes和worker_connections参数决定)而肯定。

固然,若是仅仅 为了提升并发量使服务器不出现Out Of Memory问题而去下降滑动窗口大小,那么并不合 适,由于滑动窗口太小会影响大数据量的传输速度。

rmem_default、wmem_default、 rmem_max、wmem_max这4个参数的设置须要根据咱们的业务特性以及实际的硬件成原本综 合考虑。

  • net.core.somaxconn

    选项表示当每一个网络接口接收数据包的速率比内核处理这些包的速率快时,容许发送到队列的数据包的最大数目。

  • net.ipv4.tcp_syncookies:

    设置为 1。该参数与性能无关,用于解决TCP的SYN攻击。

  • net.ipv4.tcp_max_syn_backlog:

    这个参数表示TCP三次握手创建阶段接收SYN请求队列的最大 长度,默认为1024,将其设置得大一些可使出现Nginx繁忙来不及accept新链接的状况时, Linux不至于丢失客户端发起的链接请求。

内存及磁盘资料优化

client_header_buffer_size 1k;

做为静态资源访问 1k 足够了。

客户端请求头部的缓冲区大小,默认 1k,当请求接口的时候,根据请求头数据设置 4k 整数倍。

4k 为系统内存页大小,命令 getconf PAGESIZE 内存页大小

large_client_header_buffers

image-20200329190558284

client_body_in_single_buffer

设置为 on,http 包一概写入到内存 buffer 中,若是包体超过 client_body_buffer_size 的大小,仍是会写入到磁盘文件中。

client_body_buffer_size

x64 默认 16K。定义接受请求体内存缓冲区大小,请求先写入到缓存区,超过在写入临时文件中。

client_max_body_size 100m;

设置客户端请求体最大容许大小,默认 1m。检查的是 Content-Length。设置为 0 不检查。针对具体 location 配置。防止被请求攻击,在须要调大的地方设置,不要全局设置。

sendflie on;

文件内容读取减小了内核态到用户态的拷贝,直接从内核态到网卡设备,提升了发送效率。

open_file_cache

缓存文件的存储信息。max 表示最大存储数量,超过这个数量,采用 LRU 淘汰

inactive 指定时间段,该时间段内没有被访问过的元素,会被淘汰

open_file_cache max=65535 inactive=20s;

open_file_cache_min_uses

默认为 1。与 open_file_cache 的 inactive 配合使用,若是在 inactive 指定的时间内,访问次数超过 open_file_cache_min_uses 指定的次数,不会淘汰缓存。

调大文件句柄限制

linux 一切皆文件,可是进程打开的文件数会有限制。可针对用户和进程来限制文件句柄数。

  • 文件句柄,能够针对用户,进程设置

    • 全局设置 /etc/security/limits.conf
* hard nofile 65535
* soft nofile 65535
root hard nofile 65535
复制代码
- nginx 进程配置
复制代码
worker_rlimit_nofile 20480;
复制代码

日志优化

可适当减小日志操做。好比访问静态资料的日志记录,若是你感受不重要,能够取消日志记录。这样请求资源的时候就会减小日志的磁盘 io。

# 关闭日志
access_log off;
# 禁用文件未找到的错误到日志中去
log_not_found off;
复制代码

反向代理优化

若是你用 nginx 做为代理服务器,也要减小磁盘 io 的读取。

proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 16 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_set_header Host $http_host;
proxy_set_header X-REAL-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
复制代码

Nginx 优化配置

# 配置 worker 进程所属用户,用户组
user nginx nginx;

# 配置 worker 进程数量,为避免 cpu 切换损耗,配置和系统内核数同样便可,或者 auto
worker_processes auto;

# 配置 cpu 亲和,auto 表明自动绑定
worker_cpu_affinity auto;

# nginx 进程打开文件描述符数目,此值覆盖 ulimit -n 的值。
worker_rlimit_nofile 65535;

events {
    # 用这个模型来高效处理异步事件
    use epoll;

    # 设置为 on worker 进程轮流接受新连接,官方推荐设置为 off.高负载的状况下设置为 on.
    accept_mutex on;

    # worker进程是否同时接受链接全部新请求。默认为off,表示一次只接受一个新的请求。官方推荐 off
    multi_accept on;

    # 配置 一个 woker 进程处理的链接数
    worker_connections 65535;
}
http {
    # 关闭日志
    access_log off;
    # 隐藏响应头中的有关操做系统和web server(Nginx)版本号的信息,这样对于安全性是有好处的。
    server_tokens off;
    sendfile on;
    # 设置为非零值时,可限制单个 sendfile() 调用时传输的数据量。若是没有限制,一个快速 链接可能会彻底占用工做进程。
    sendfile_max_chunk 5m;
    # tcp_nopush 和 tcp_nodeny 能够一块儿生效
    # 等数据包累计到必定大小发送,启用 sendfile 生效
    tcp_nopush on;
    # 该选项仅在链接转换到 keep-alive ,长链接状态时启用。让 tcp 尽快发包。
    tcp_nodelay on;
    # 为了尽快释放链接,能够设置小点. 15 至 30
    keepalive_timeout 15;

    # 客户端请求头部的缓冲区大小,默认 1k,当请求接口的时候须要设置 4k 整数倍.内存设置为系统内存页大小,命令 getconf PAGESIZE 内存页大小
    client_header_buffer_size 4k;

    large_client_header_buffers 8 8k;

    # 根据需求设置,接口请求能够设置大些
    client_body_buffer_size 128k;

    # 设置客户端请求体最大容许大小,默认 1m。检查的是 Content-Length。设置为 0 不检查。针对具体 location 配置
    client_max_body_size 1m;


    # 下面这个参数将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,
    # inactive是指通过多长时间文件没被请求后删除缓存。
    open_file_cache max=262140 inactive=20s;
    # 下面这个是指多长时间检查一次缓存的有效信息。
    open_file_cache_valid 30s;
    # open_file_cache指令中的inactive参数时间内文件的最少访问次数,低于这个数,缓存清除
    open_file_cache_min_uses 1;
    open_file_cache_errors on;

    reset_timedout_connection on;
    client_body_timeout 10;
    send_timeout 2;

    # 限制每一个 ip 的链接数
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

    # 限制每一个 ip 每秒的请求数
    limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;

    gzip on;
    # 在响应头中增长,Vary: Accept-Encoding
    gzip_vary on;
    # gzip压缩级别1-9,数字越大压缩效果越好,压缩时间也就越长CPU越高
    gzip_comp_level 5;
    # 申请内存时大小,若是源文件 9k,超过了 8K,那会申请 16*8K。
    gzip_buffers 8 128k;
    gzip_min_length 5K;
    gzip_proxied any;
    gzip_disable msie6;
    gzip_http_version 1.1;
    # 文本(js、text、css、xml、json)压缩比较好,图片已经进行过压缩,在压缩,效果不是很明显,还浪费 cpu
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss application/rss+xml application/atom+xml image/svg+xml;

    # 安全相关 header
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Feature-Policy "autoplay 'none'; camera 'none'" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;


    server {
        listen 80 backlog=262144;

        limit_conn conn_limit_per_ip 10;
        limit_req zone=req_limit_per_ip burst=10 nodelay;
        # assets, media
        location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
            # 强缓存,时间为一年,浏览器和 cdn 中间件能够缓存
            add_header Cache-Control "max-age=31536000";
            etag off;
            access_log off;
            # 禁用文件未找到的错误到日志中去
            log_not_found off;
        }

        # svg, fonts
        location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
            # 强缓存,时间为一年,浏览器和 cdn 中间件能够缓存
            add_header Cache-Control "max-age=31536000";
            etag off;
            access_log off;
            # 禁用文件未找到的错误到日志中去
            log_not_found off;
        }
    }

}
复制代码

资料参考

http-security-headers

Nginx Performance Tuning – Tips & Tricks

《深刻理解 Nginx 模块开发与架构设计》。


本文由 张攀钦的博客 www.mflyyou.cn/ 创做。 可自由转载、引用,但需署名做者且注明文章出处。

如转载至微信公众号,请在文末添加做者公众号二维码。微信公众号名称:Mflyyou

img
相关文章
相关标签/搜索