nginx优化上

Nginx优化上

一、优化概述

给你一套架构的优化思路

1、先摸清楚状况

1、首先了解整套架构的链路和分层--->画出架构/链路图
即用户发送一个请求,这个请求会先打到哪里,再打到哪里,然后打到哪里

2、其次要了解这套架构上承载的业务特点
例如:电商网站的抢购模式,平时没啥流量,但到了抢购时间点则流量特别大

2、再发现瓶颈在哪里

网站反馈慢,那要从用户发送的请求开始,查看沿途经过的点,分析出哪个点导致的慢


参考上一步分析出的链路:
用户请求-----》负载均衡-----》应用-----》数据库与数据库缓存层
                                -----》文件服务器层


一些排查方式举例
1、有些慢可以直接计算出来
峰值qps、系统应用集群能承载的qps,算出集群该扩容那就扩容

2、无法直接算出来的需要排查
2.1、查看沿途的访问日志,例如mysql的慢查询日志
2.2、top命令、netstat、或或ngx_http_stub_status_module查看链接数
来确认资源使用情况,是否有超负载、内存用完、连接过多的情况

3、有针对性的进行优化

一、架构高性能优化思路
    优化思路:
         (1)高频读:就少读、就近读、读缓存 
         (2)高频写:就少写、数据拆分、漏斗写,buffer写 
    优化步骤:
         (1)先细分、分层,分好了,才能针对性处理,对症下药--》一群人分好队伍
         (2)再放置,不同资源部署到不同的地方------》不同的队伍扔到不同地方
         (3)最后优化,有针对性的进行优化--------------------》单独照顾某个地方
    优化效果:
          例如动静分离、冷热分离,即分流了压力又做到了隔离保护,从而达到高性能的目的
                                                           
二、架构维度,每一层该如何优化举例
1、数据库层
  数据库慢查询---》优化sql、索引、加数据库缓存层
2、web层
  预估的峰值qps、低峰期压测出每台web能抗的qps,发现web服务器少---》扩机器
  查看到个别web的负载高、内存使用率大---》降权重,扩机器

3、负载均衡机器负载太高---》多级负载均衡、买硬件F5

4、文件服务器层
   -----》分布式存储

5、网络
   丢包、延迟----》优化网络环境、升级网络设备
   带宽不够------》加带宽
   访问距离远-----》CDN

6、针对棘手的问题---》分离出来一层,单独处理
动静分离
冷热分离

三、单机通用优化点:
1、硬件
    负载均衡:cpu核多一些、内存大一些
    应用层:无特殊要求,因为有很多应用服务器,可以用权重控制转发比例
    文件服务器:内存、磁盘大一些
    数据库:内存、磁盘都要大一些
    数据库缓存:内存大一些

2、系统
   内核优化参数
   (1) ipv4相关: /proc/sys/net/ipv4/...
   (2) tcp半链接池、全连接池

3、软件---服务
   例如nginx的优化,详解如下

4、软件---应用
   每个程序都有自己环境相关优化参数

二、系统优化

详解:https://egonlin.com/?p=237

主要设置

2.1、文件描述符数量、进程数

#1、系统全局设置
在/etc/security/limits.d/下放配置文件优先级更高,并且无需重启系统,退出当前终端重新进入即可生效
cat > /etc/security/limits.d/k8s.conf <<'EOF' 
* soft nofile 65535 
* hard nofile 131070 
EOF 

*       #所有用户
soft    #当超过设置的文件句柄数时,仅提示
hard    #当超过设置的文件句柄数时,直接限制

#2.查看文件句柄数设置
ulimit -Sn 
ulimit -Hn

#3.查看打开的文件句柄数
[root@lb01 ~]# lsof | wc -l
2945
[root@web01 ~]# lsof | wc -l
12490

#4.查看指定服务的打开文件句柄数
[root@web01 ~]# lsof -p 13592 | wc -l

2.2、内核参数优化

[root@lb01 ~]# vim /etc/sysctl.conf # 
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384 # --------半连接队列
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384 # --------------全连接队列
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
net.ipv4.ip_forward = 1

三、nginx优化

3.1 单节点nginx优化

全局配置优化

worker_processes  4; # 通常设置为auto就行,有几个核就设置为几
worker_rlimit_nofile 65535;  # 配合着要把文件描述符调大

events块

events {
    use epoll;  # 使用epoll网络io模型
    worker_connections 1024;  # 调大连接数
}

http块

http {
    #2、网络io优化参数
    #2.1 开启sendfile特性可以显著提高静态文件(如图片、CSS、JavaScript文件等)传输的效率
    # 原理如下
    # 开启sendfile后可以减少数据在操作系统内核和用户空间之间的拷贝次数。
    # 没有 sendfile 的情况下,传输文件通常需要经历如下步骤,数据需要在用户空间和内核空间之间进行两次拷贝。
    # (1)从硬盘读取文件到用户空间的缓冲区(内核→用户空间)
    # (2)将读取的数据从用户空间缓冲区写入到操作系统的网络缓冲区(用户空间→内核)
    # (3)操作系统网络缓冲区发送数据到网络(内核→网络)
    # 当开启了 sendfile 之后,这个操作简化了,并且可以避免将数据从内核空间拷贝到用户空间。sendfile 系统调用可以直接在内核中传输数据:
    # (1)内核会将数据从文件系统缓冲区直接发送到网络堆栈,无需先拷贝到用户空间,然后再从用户空间拷贝到内核的网络堆栈
    # (2)数据可以直接在内核地址空间中移动,避免了额外的上下文切换和数据复制开销
    # 所以,sendfile 能够减少 CPU 的使用,减少操作系统的上下文切换,并允许更快地传输文件数据,特别是对于大型文件的传输
    sendfile     on;
    #2.2 通常与sendfile一起用,当 tcp_nopush 设置为 on 时,Nginx 将尽可能发送较大的 TCP 数据包,减少 TCP 报文的数量,提高传输效率。这对于减少网络传输中的 TCP 慢启动阶段,减少网络延迟和提高网络吞吐量非常有用。这在传输大型文件或使用 HTTP/1.1 的 Keep-Alive 长连接时特别有效。
    tcp_nopush     on; 
    #2.3 开启Nagle算法,数据将会尽快发送出去,而不是等待缓冲区满或者接收到ACK。这会减少延迟,但可能会造成网络利用率低。这个选项在处理需要快速响应的短数据流(例如HTTP/1.1的keep-alive连接)时非常有用。
    tcp_nodelay     on;
    #2.4、控制长连接的两个参数:
    keepalive_timeout  65; # 开启长连接:如果客户端在65秒内没有再次发送新的请求,那么Nginx将关闭这个连接,反之如果在65秒内有新的请求到来,那么这个连接会保持开启,等待处理新的请求
    keepalive_requests 100; # 默认情况下,Nginx的keepalive_requests 是设置为100,这个设置针对的是每个长连接在关闭前能处理的最大请求数量。你可以根据需要调整这个值。
 
    #2.5开启gzip压缩,节省带块加速网络传输
    gzip  on;
 
    # 3、控制客户端请求头的缓冲区大小和数量:应对请求头过大的情况
    client_header_buffer_size    128k;  #  设定用于保存客户端请求头的缓冲区的大小,当客户端发送的请求头超过这个大小时,Nginx 将使用临时文件来保存请求头。这可以防止恶意客户端发送大量数据来消耗服务器资源
    large_client_header_buffers  4 128k; # 如果请求头过大,可以使用多个缓冲区来保存。格式为 <数量> <大小>。<数量>代表缓冲区数量,<大小>代表每个缓冲区的大小。

server块:启用线程池、reuseport独享全连接队列

#  全局新增
thread_pool egon_pool threads=3 max_queue=1024; # 定义线程池

http {
    #aio threads;
    aio threads=egon_pool; # 启用线程池

    # 启用线程池与reuseport并不冲突
    server {
        listen 8089 reuseport backlog=10240;

3.2 nginx做代理服务器的代理配置优化

(1)配置负载均衡代理到web的长连接

[root@lb01 ~]# vim /etc/nginx/conf.d/linux.keep.com.conf
upstream tomcat {
    server 172.16.1.7:8080;
    keepalive 8;                #配置开启长连接
}

server {
    listen 80;
    server_name linux.keep.com;

    location / {
        proxy_pass http://tomcat;
        proxy_http_version 1.1;         #代理带后端的http版本
        proxy_set_header Connection "";    #清除请求头字段
        include proxy_params;
    }
}

(2)配置web代理到php保持长连接

[root@web01 ~]# vim /etc/nginx/conf.d/linux.wp.com.conf 
upstream php_server {
    server 127.0.0.1:9000;
}

server {
    listen 80;
    server_name linux.wp.com;

    location / {
        root /code/wordpress;
        index index.php;
    }

    location ~* \.php$ {
        fastcgi_pass php_server;
        fastcgi_param SCRIPT_FILENAME /code/wordpress/$fastcgi_script_name;
        fastcgi_param HTTPS on;
        fastcgi_keep_conn on;  # 开启长连接
        include fastcgi_params;
    }
}

(3)代理优化配置

[root@lb01 ~]# cat /etc/nginx/proxy_params 
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;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
proxy_next_upstream http_500 http_502 http_503 http_504;

然后在文件中引入
    location / {
        proxy_pass http://tomcat;
        include proxy_params; # -----》引入上面的文件
    }

四、静态资源缓存

联系管理员微信tutu19192010,注册账号

上一篇
下一篇
Copyright © 2022 Egon的技术星球 egonlin.com 版权所有 帮助IT小伙伴学到真正的技术