首页 > 系统相关 >性能优化 - Nginx & Linux

性能优化 - Nginx & Linux

时间:2023-07-14 15:48:23浏览次数:48  
标签:core application worker tcp Nginx ipv4 Linux net 优化

性能优化 - Nginx & Linux

来自 鑫哥 [鑫哥的技术思维]2022-05-07 09:26 发表于湖北

纲要

  • Nginx 优化后的完整配置
  • Linux 内核参数优化
  • 修改最大打开文件句柄数

Nginx 优化后的完整配置

# 核心参数(其他参数大部分情况下用不到)

# user USERNAME [GROUP]
# 解释:指定运行nginx的worker子进程的属主和属组,其中属组可以不指定
user  nginx;

# worker_processes NUMBER | auto
# 解释:指定nginx启动的worker子进程数量
# 【*auto:自动设置为物理CPU核心数】
worker_processes  auto;

# pid DIR
# 解释:指定运行nginx的master主进程的pid文件存放路径
pid /opt/nginx/logs/nginx.pid;

# worker_rlimit_nofile NUMBER
# 解释:指定worker子进程可以打开的最大文件句柄数
# 【系统最大打开65535,每个子进程打开数乘子进程数,实际也不会超过65535】
# 这个值需要调大,最好与  ulimit -n  的值保持一致。
worker_rlimit_nofile 65535;

# worker_rlimit_core SIZE
# 指定worker子进程异常终止后的core文件,用于记录分析问题
worker_rlimit_core 50M;
working_directory /opt/nginx/tmp;#【必须对子进程用户赋写权限】

# 解释:将每个worker子进程与CPU物理核心绑定
# 【master负责调度,worker负责处理请求】
# 【假设CPU有4个核心,某一时刻worker1获取到了CPU1的工作调度时间片,时间片过后worker1从CPU1上面撤下来,CPU1去处理其他事件,下一时刻可能是CPU2、CPU3的时间片调度到了worker1上面,那么worker1就会在其他CPU上面工作,进程与CPU的调度切换是有损耗的,worker1如果绑定了CPU1,worker1将永远等待CPU1的调度,充分利用CPU缓存】
# 【【主要作用:将每个worker子进程与特定CPU物理核心绑定,优势在于:避免同一个worker子进程在不同的CPU核心上切换,缓存失效,降低性能;其并不能真正避免进程切换(进程切换是CPU工作特性)】】
# -- worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;# 8核心,8个worker
# -- worker_cpu_affinity 01 10;# 2核心,2个worker
worker_cpu_affinity 0001 0010 0100 1000;# 4核心,4个worker

# 解释:指定worker子进程的nice值,以调整运行nginx的优先级,通常设定为“负值”,以优先调用nginx
# 【值越小越优先;nice设定范围为-20到+19】
worker_priority -20;

# 指定worker子进程优雅退出时的超时时间,不管5秒内是否处理完,都强制退出
worker_shutdown_timeout 5s;

# worker子进程内部使用的计时器精度,调整时间间隔越大,系统调用越少,有利于性能提升;反之,系统调用越多,性能下降
# 比如某些计时的操作,worker需要去获取内核时间,频繁跟内核打交道会降低性能
timer_resolution 100ms;

# daemon on | off
# 设定nginx的运行方式,前台还是后台,前台用户调试,后台用于生产
daemon on;


events {
    # Nginx使用何种事件驱动模型
    # 【高并发场景下,I/O多路复用使用epoll模型,提高效率】
    use epoll;
    
    # 单个worker子进程能够处理的最大并发连接数,多核情况最大其实达不到65535,
    worker_connections  65535;
    
    # 是否打开负载均衡互斥锁,默认off(当master接收到请求时,会给每个worker发送消息去唤醒,状态为on时,则会有一个负载均衡锁,master会轮流发给每一个)
    accept_mutex off;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
    #access_log  logs/access.log  main;
    
    # 开启高效的 零拷贝技术 进行文件传输;
    # 这样只需要 2 次上下文切换,和 2 次数据拷贝,在内核态即可完成,由DMA进行文件搬运,不需要CPU参与
    sendfile       on;
    
    # 必须在sendfile开启时才有效,防止网路阻塞,减少网络报文段的数量(将响应头和正文的开始部分一起发送,而不一个接一个的发送)
    tcp_nopush     on;
    
    # 客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接 
    keepalive_timeout  60;            

    # 防止网络阻塞
    tcp_nodelay on;                 

    # 客户端请求头部的缓冲区大小,根据系统分页大小来设置,命令 getconf PAGESIZE 取得分页大小
    client_header_buffer_size 4k;        

    # 为打开文件指定缓存,默认是没有启用的,max 指缓存数量,建议和打开文件数一致,inactive 指经过多长时间文件没被请求后删除缓存
    open_file_cache max=65536 inactive=30s;  

    # 多长时间检查一次缓存的有效信息
    open_file_cache_valid 30s;          

    # open_file_cache 指令中的 inactive 参数时间内文件的最少使用次数
    # 如果超过这个数字,文件描述符一直是在缓存中打开的,如果一个文件在 inactive 时间内一次没被使用,它将被移除
    open_file_cache_min_uses 1;         
                            
    # 设置请求头的超时时间,如果超过这个时间没有发送任何数据,nginx将返回request time out的错误
    client_header_timeout 15;          

    # 设置请求体的超时时间,超过这个时间没有发送任何数据,和上面一样的错误提示
    client_body_timeout 15;            

    # 告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间
    reset_timedout_connection on;        

    # 应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接
    send_timeout 15;                

    # 上传文件大小限制
    client_max_body_size 10m;          

 
    
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location /video/ {
            sendfile  on;
            
            # 当文件大小超过8M时,启用AIP与directio
            aio       on;
            directio  8m;
        }
        
    # HTTPS server
    server {
    
        # 开启http2
        # http2 在底层传输做了很大的改动和优化:
        # 1,每个服务器只用一个连接,节省多次建立连接的时间,在TLS上效果尤为明显
        # 2,加速 TLS 交付,HTTP/2 只耗时一次 TLS 握手,通过一个连接上的多路利用实现最佳性能
        # 3,更安全,通过减少 TLS 的性能损失,让更多应用使用 TLS,从而让用户信息更安全
        listen       443 ssl http2;
        server_name  localhost;
        
        ## 证书部分
        #ECC证书
        # 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,运算速度更快,同等安全条件下,ECC 算法所需的 Key 更短,所以 ECC 证书文件体积比 RSA 证书要小一些。
        ssl_certificate ecc.crt; 
        
        #ECC密钥 
        ssl_certificate_key ecc.key; #ECC密钥  
        ssl_certificate      cert.pem; # RSA证书
        ssl_certificate_key  cert.key; # RSA密钥
        
        # TLS 握手优化
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        keepalive_timeout    75s;
        keepalive_requests   100;

        
        # 支持TLSv1.3
        ssl_protocols    TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_ciphers        TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
        
        # 开启 1.3 o-RTT
        ssl_early_data     on;
  
        ssl_prefer_server_ciphers  on;
        
        
        # gzip 
        gzip               on;
        
        # 压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源
        gzip_comp_level    6;
        
        # 设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0
        gzip_min_length    1k;
        
        # 用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩)
        # 缩类型,匹配MIME型进行压缩,不能用通配符 text/* text/html默认已经压缩 (无论是否指定)
        # 设置哪压缩种文本文件可参考 conf/mime.types
        gzip_types        text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;
        
        
        # brotli:Google 推出的无损压缩算法,有以下优势:
        # 1,针对常见的 Web 资源内容,Brotli 的性能要比 Gzip 好 17-25%;
        # 2,Brotli 压缩级别为 1 时,压缩速度是最快的,而且此时压缩率比 gzip 压缩等级为 9(最高)时还要高;
        brotli            on;
        brotli_comp_level    6;
        brotli_min_length    1k;
        brotli_types    text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;


        location / {
            root   html;
            index  index.html index.htm;
        }
    }
}

支持 TLS1.3 和 brotli ,都需要编译时引入相应模块

cd /opt/$nginxVersion/
./configure \
--prefix=/usr/local/nginx \  ## 编译后安装的目录位置
--with-openssl=/opt/$OpenSSLVersion  \ ## 指定单独编译入 OpenSSL 的源码位置
--with-openssl-opt=enable-tls1_3 \ ## 开启 TLS 1.3 支持
--with-http_v2_module \ ## 开启 HTTP/2 
--with-http_ssl_module \ ## 开启 HTTPS 支持
--with-http_gzip_static_module \ ## 开启 GZip 压缩
--add-module=/opt/ngx_brotli ## 编译入 ngx_BroTli 扩展

make && make install ## 编译并安装

Linux 内核参数优化

  • 修改文件:/etc/sysctl.conf
  • 执行 /sbin/sysctl -p,使配置生效
# 表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直接限制最大并发连接数,需根据实际情况配置
fs.file-max = 999999                           

# 控制系统调试内核的功能,不同的值对应不同的功能
# 0 完全禁用 sysrq 组合键
# 1 启用 sysrq 组合键的全部功能
# 2 启用控制台日志级别控制
# 4 启用键盘控制(SAK、unraw)
# 8 启用进程的调试信息输出等
# 16 启用同步命令
# 32 启用重新挂载为只读
# 64 启用进程信号(终止、杀死、溢出杀死)
# 128 允许重启/关机
# 256 控制实时任务的优先级控制(nicing)
kernel.sysrq = 0                  

# core_uses_pid 可以控制 core 文件的文件名中是否添加 pid 作为扩展名
# 设置为1,表示添加 pid 作为扩展名,生成的 core 文件格式为 core.xxx;设置为0(默认),表示生成的 core 文件统一命名为 core
kernel.core_uses_pid = 1             
                                    

# 规定了一个消息队列的最大值,即一个消息队列的容量,msgmnb 控制可以使用的共享内存的总页数
# Linux共享内存页大小为4KB,共享内存段的大小都是共享内存页大小的整数倍
# 一个共享内存段的最大大小是 16G,那么需要共享内存页数是16GB / 4KB = 16777216KB / 4KB = 4194304(页)
kernel.msgmnb = 65536               
                            
# 进程间的消息传递是在内核的内存中进行的。msgmax 指定了消息队列中消息的最大值(65536B=64KB)
kernel.msgmax = 65536               

# 内核所允许的最大共享内存段的大小(bytes)
kernel.shmmax = 68719476736            

# 表示在任何给定时刻,系统上可以使用的共享内存的总量(bytes)
kernel.shmall = 4294967296   

# 表示内核套接字发送缓存区默认的大小
net.core.wmem_default = 8388608         

# 表示内核套接字接受缓存区默认的大小
net.core.rmem_default = 8388608         

# 表示内核套接字接受缓存区的最大大小
net.core.rmem_max = 16777216           

# 表示内核套接字发送缓存区的最大大小
net.core.wmem_max = 16777216           

# 接收自网卡,但未被内核协议栈处理的报文队列长度
net.core.netdev_max_backlog = 262144  


# web 应用中 listen 函数的 backlog 默认会给我们内核参数的
# 对于一个TCP连接,Server与Client需要通过三次握手来建立网络连接
# 当三次握手成功后,我们可以看到端口的状态由LISTEN转变为ESTABLISHED,接着这条链路上就可以开始传送数据了
# 每一个处于监听(Listen)状态的端口,都有自己的监听队列.监听队列的长度与如somaxconn参数和使用该端口的程序中listen()函数有关
# somaxconn定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128
# 对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多
# 大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助
net.core.somaxconn = 40960  

# 不充当路由器
net.ipv4.ip_forward = 0   

# 控制系统是否开启对数据包源地址的校验
# 0 不开启源地址校验
# 1 开启严格的反向路径校验。对每个进来的数据包,校验其反向路径是否是最佳路径。如果反向路径不是最佳路径,则直接丢弃该数据包
# 2 开启松散的反向路径校验。对每个进来的数据包,校验其源地址是否可达,即反向路径是否能通(通过任意网口),如果反向路径不同,则直接丢弃该数据包
net.ipv4.conf.default.rp_filter = 1       

# 使用sysrq组合键是了解系统目前运行情况,为安全起见设为0关闭
net.ipv4.conf.default.accept_source_route = 0        

# 启用有选择的应答(1表示启用)
# 通过有选择地应答乱序接收到的报文来提高性能,让发送者只发送丢失的报文段,(对于广域网通信来说)这个选项应该启用,但是会增加对CPU的占用
net.ipv4.tcp_sack = 1               

# tcp窗口大于64K时,必须开启此值
net.ipv4.tcp_window_scaling = 1         

# TCP读缓存的最小值、默认值、最大值,单位字节
net.ipv4.tcp_rmem = 10240 87380 12582912    

# TCP读缓存的最小值、默认值、最大值,单位字节
net.ipv4.tcp_wmem = 10240 87380 12582912   

# TCP的内存大小,单位是页,1页等于4096字节,单位为页的数量
net.ipv4.tcp_mem = 94500000 915000000 927000000  

# 系统中最多有多少个 TCP 套接字不被关联到任何一个用户文件句柄上
# 这个限制仅仅是为了防止简单的 DoS 攻击,如果增加了内存之后,更应该增加这个值
net.ipv4.tcp_max_orphans = 3276800        

# SYN队列的长度,默认为1024,加大队列长度为262144,可以容纳更多等待连接的网络连接数
net.ipv4.tcp_max_syn_backlog = 262144      

# 用于设置时间戳,可以避免序列号的卷绕
# 一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。设置为 0 表示将其关掉
net.ipv4.tcp_timestamps = 0            

# 内核放弃连接之前发送 SYN+ACK 包的数量
# 被动建立连接时,发送SYN/ACK的重试次数
net.ipv4.tcp_synack_retries = 1         

# 主动建立连接时,发送SYN的重试次数
net.ipv4.tcp_syn_retries = 1           

# 开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 1            

# 开启重用。作为客户端时,新连接可以使用仍然处于 TIME-WAIT 状态的端口,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1  

# TIME_WAIT 状态连接的最大数量,超出后直接关闭连接
net.ipv4.tcp_max_tw_buckets = 6000 

# fin_wait1状态,发送fin报文的重试次数,0相当于8
net.ipv4.tcp_orphan_retries = 0

# fin_wait2状态,默认的 TIMEOUT 时间
net.ipv4.tcp_fin_timeout = 15            

# 当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时
net.ipv4.tcp_keepalive_time = 1200  

# 探测包发送间隔
net.ipv4.tcp_keepalive_intvl = 75

# 探测包重试次数
net.ipv4.tcp_keepalive_probes = 6

#开启SYN Cookies 当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1    

# 建立连接时的本地端口可用范围
net.ipv4.ip_local_port_range = 1024 65000    

修改最大打开文件句柄数

编辑文件:/etc/security/limits.conf

* soft nofile 65535
* hard nofile 65535

标签:core,application,worker,tcp,Nginx,ipv4,Linux,net,优化
From: https://www.cnblogs.com/starkzz/p/17553839.html

相关文章

  • Linux下chkconfig命令详解(service)
    Linux下chkconfig命令详解(service)一、释义chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息。谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接。二、使用语法chkconfig[--add][--del][--list][系统服务]或chkconfig[--level......
  • Cygwin、Linux Bash计算某个时刻偏移一定时间长度后的时间通用函数:datetimecount
    datetimecount函数代码datetimecount(){ #计算某个日期时间偏移一定时间长度后的时刻(目前主要供录制IPTV直播源时计算视频时长使用) #$1-->偏移量:符合date命令的描述参数即可,也支持传递标准时间格式:eg:+01:23:35(标记符号(加减号)可省略,小时字段可省略) #$2-->要计算偏移......
  • nginx安装
    将nginx源码包下载下来,官网下载地址:http://nginx.org/en/download.html,选择stableverson版本,以nginx-1.18.0为例,材料包中已下载,进入存放nginx-1.18.0.tar.gz源码包的目录,用解压命令解压到当前目录tar-xzvfnginx-1.18.0.tar.gz进入解压后的nginx-1.18.0目录里,使用cofigure......
  • ubuntu20.04 配置编译安装nginx的systemctl启动命令
    vim/usr/lib/systemd/system/nginx.service[Unit]Description=nginx-highperformancewebserverAfter=network.targetremote-fs.targetnss-lookup.target[Service]Type=forkin......
  • Linux 服务器安全加固十条建议
    1、https://www.51cto.com/article/695880.html1、设置复杂密码服务器设置大写、小写、特殊字符、数字组成的12-16位的复杂密码,也可使用密码生成器自动生成复杂密码,这里给您一个链接参考:https://suijimimashengcheng.51240.com/ 复制echo "root:wgr1TDs2Mnx0XuAv" | c......
  • Linux版本分类
    Linux的发行版本大致可以分为两类,一类是商业公司维护的发行版本,一类是社区组织维护的发行版本。前者以著名的RedHat (RHEL红帽)为代表,后者以Debian为代表Redhat系列的包管理方式采用的是基于RPM包和YUM包的管理方式,包分发方式是编译好的二进制文件RHEL(RedhatEnterpri......
  • Linux常用命令大全
    Linux常用命令大全1.Linux管理文件和目录的命令命令 功能 命令 功能Pwd 显示当前目录 ls 查看目录下的内容Cd 改变所在目录 cat 显示文件的内容Grep 在文件中查找某字符 cp 复制文件Touch 创建文件 mv 移动文件Rm 删除文件 rmd......
  • Java优化递归查询Mysql节点树数据
    示例目前有一个功能:任务计划管理,必然存在多级子任务的父子级关系,每个任务还会存在其它数据的关联表。mysql无法一次性递归查出想要的数据结构,想必很多人都会是通过根目录递归查询数据库的方式查出树结构数据。如果节点数较多,就会造成大量请求Mysql查询,效率会很低。那么如......
  • nginx tlsv1.3配置
    server{#这里开始listen443ssl;server_namelocalhost;ssl_certificate/usr/local/nginx/conf/cert/9169645__shhanqian.com.pem;#证书的路径ssl_certificate_key/usr/local/nginx/conf/cert/9169645__shha......
  • linux文件内容查看命令
    1、https://www.cnblogs.com/my-first-blog-lgz/p/13353051.html文件内容查看 1.cat:从第一行开始显示文件内容。用来读文章,或者读取配置文件 2.tac:从最后一行开始显示,可以看出tac是cat倒着写。 3.nl:显示的时候,顺便输出行号。看代码的时候希望显示行号。 4.more:一页一页显示......