当前位置: 首页 > news >正文

【Nginx】性能优化与实战(上)

本文详细介绍了Nginx的KeepAlive、反向代理、Gzip压缩等核心功能的配置要点。KeepAlive部分讲解了连接复用、超时设置及请求数限制;反向代理部分解析了连接超时、缓冲机制及Header设置;Gzip压缩部分说明了压缩类型选择、压缩级别及缓存控制。最后提供了前端部署案例和SSI技术的应用场景分析。文章重点阐述了各项配置的原理、使用场景及参数调优建议,帮助开发者根据实际需求进行合理的Nginx性能优化。

一、KeepAlive

1.使用场景
  • 可预知的连续操作:比如加载页面HTML后马上去请求JS和CSS资源等
  • 减少连接开销:通过复用连接,降低服务器的CPU和网络延迟
2.客户端使用

keepalive_timeout timeout [header_timeout];

  • 作用:设置一个KeepAlive连接在被服务器关闭之前,最长的空闲等待时间。

  • timeout:指定了空闲超时时间,默认为75秒。如果设置为0,则表示禁用KeepAlive。

  • header_timeout(可选):在响应头Keep-Alive: timeout=time中设置一个值,这个值可以被某些浏览器识别和使用。

  • 示例keepalive_timeout 65 65; 表示服务器空闲65秒后关闭连接,并通知浏览器连接的超时时间也是65秒。

keepalive_requests number;

  • 作用:定义了单个KeepAlive连接上可以处理的最大请求数量。当请求数达到这个阈值后,连接将被关闭。

  • 默认值:1000。

keepalive_time time;

  • 作用:设置一个KeepAlive连接总的存活时长。无论连接是否活跃,只要从建立开始超过了这个时间,就会被强制关闭。这是一个较新的指令(Nginx 1.19.10+)。

  • 示例keepalive_time 1h;

send_timeout time;

  • 作用:设置向客户端发送响应的超时时间。这个超时不是指整个响应的传输时间,而是指两次连续的Nginx向Browser写数据操作之间的最大间隔时间。

  • 重要陷阱:如果Nginx后面连接的应用有一个耗时很长的同步操作(例如超过60秒),在操作完成前Nginx没有向客户端发送任何数据,那么这个连接可能会因为send_timeout而被Nginx断开,导致用户收到错误。

3.上游服务器使用

在server或者location中:

proxy_http_version 1.1;

  • 作用:必须将代理请求的HTTP协议版本设置为1.1。因为HTTP/1.1默认支持KeepAlive,而HTTP/1.0需要显式声明Connection: keep-alive头。

proxy_set_header Connection "";

  • 作用:清除从客户端请求中继承来的Connection头。如果客户端的请求头是Connection: close,这个头默认会传递给后端服务器,导致后端用完就关闭连接。将其设置为空字符串,可以避免这种情况,从而让Nginx来管理与后端的连接状态。

在upstream中:

keepalive connections;

  • 作用:核心指令。定义了每个worker进程缓存的到上游服务器的最大空闲连接数。当有新的请求需要代理时,Nginx会优先从这些空闲连接中选取一个来使用,而不是新建连接。这个值不宜过大,但也不能太小,需要根据并发量和后端服务器的处理能力来设定。

  • 总连接数:系统总的空闲长连接数是 keepalive 的值乘以 worker_processes 的数量。例如,worker_processes 4;keepalive 128; 意味着Nginx最多会保持 4 * 128 = 512 个到后端的空闲连接。你需要确保后端服务器(Tomcat等)的最大连接数设置能够承受这个数量。

二、反向代理

1.连接与超时指令

这些指令控制Nginx和上游服务器之间连接的生命周期和容错能力

proxy_connect_timeout

  • 作用:定义Nginx与上游服务器建立TCP连接的超时时间。

  • 为什么要设置:这是实现“快速失败”(Fast-Fail)机制的关键。如果某个后端服务已经宕机或网络不通,Nginx不必长时间等待,而可以在这个设定的时间内快速判断连接失败,然后根据策略(例如proxy_next_upstream)尝试连接下一个后端服务。这可以有效防止请求在无效的后端服务上积压,提升系统的可用性。

  • 好比:打电话时,拨号后等待对方“接听”的最长时间。如果一直没人接,你就会挂断。

proxy_send_timeout

  • 作用:定义Nginx向后端服务发送请求数据时,两次连续写入操作之间的超时时间。请注意,它不是发送整个请求的总耗时。

  • 为什么要设置:用于防止与一个“假死”的后端服务建立连接后,在发送数据时卡住。比如,后端服务的接收缓冲区满了,无法再接收新的数据,此时Nginx的发送操作就会阻塞,这个指令可以防止无限期阻塞。

  • 好比:你给朋友发一个大文件,发送过程中,如果对方的网络突然卡住,导致你的发送进度条长时间不动,这个指令就会触发超时,中断发送。

proxy_read_timeout

  • 作用:定义Nginx从后端服务读取响应数据时,两次连续读取操作之间的超时时间。

  • 为什么要设置:这是最常用也是最重要的超时设置之一。它用于防止后端服务处理请求时间过长。如果后端因为复杂的业务逻辑、慢SQL或者死循环而长时间没有返回任何数据,Nginx会在等待超过这个时间后主动断开连接,并向客户端返回504 Gateway Time-out错误。这可以避免客户端请求被无限期挂起。

  • 好比:你问朋友一个问题,等待他回答的最长时间。如果他一直沉默不语,超过了你的耐心限度,你就会不等了直接走开(返回504)。

2.代理缓冲指令

proxy_request_buffering

  • 作用:决定是否启用客户端请求体的缓冲。

  • 工作模式

    • on (默认):Nginx会完整接收客户端发送过来的全部请求体(比如POST的JSON数据、上传的文件),将其存放在内存或临时文件中,然后再一次性地将完整请求发送给后端服务。

    • off:Nginx会边接收客户端的数据,边向上游服务器转发,实现“流式”传输。

  • 为什么要这样设计:默认开启缓冲,可以大大减轻后端服务的压力。后端服务可以一次性收到一个完整的、干净的HTTP请求,处理完后立即释放连接,而不必去适应客户端可能很慢的网络速度。只有在上传超大文件等特定场景下,为了避免Nginx磁盘I/O成为瓶颈,才会考虑关闭它。

proxy_buffering

  • 作用:这是总开关,决定是否启用对上游服务器响应的缓冲。

  • 工作模式

    • on (默认):Nginx会尽可能完整地接收后端服务返回的所有响应数据,存放在自己的缓冲区(内存或临时文件)中,然后再开始向客户端发送。

    • off:Nginx会边接收后端的数据,边同步地转发给客户端。

  • 为什么要这样设计:同样是为了解耦和保护后端。Nginx可以迅速接收完后端的数据,让后端服务“功成身退”,去处理其他请求。然后Nginx再根据客户端的网速慢慢地将数据发送给客户端,整个过程后端服务无需参与。这极大地提高了后端服务的吞吐能力。

当proxy_buffering on;时,以下指令共同定义缓冲区的行为:

proxy_buffer_size

  • 作用:设置用于存储上游响应第一部分(主要是HTTP响应头)的缓冲区大小。这块缓冲区通常不需要很大,但必须足够大以容纳所有的响应头。

proxy_buffers

  • 作用:设置用于存储上游响应**主体(body)**的缓冲区。它由缓冲区数量和每个缓冲区的大小两部分组成。例如,proxy_buffers 32 128k; 表示Nginx会为每个连接分配32个128KB的内存块用于缓冲响应体,总大小为 32 * 128KB = 4MB

proxy_max_temp_file_size

  • 作用:定义了这个临时文件的最大尺寸。如果响应数据连这个临时文件都装不下,Nginx会放弃缓冲,直接同步转发后续数据(如果可能),或者报错。

proxy_temp_path

  • 作用:指定用于存放这些临时文件的目录路径。levels参数可以创建分级子目录,避免单个目录下文件过多影响性能。

proxy_temp_file_write_size

  • 作用:设置Nginx在向临时文件写入数据时,每次写入的数据块大小。

3.Header设置指令

proxy_set_header

  • 作用:允许你修改或添加从Nginx发往上游服务器的请求头。

  • 为什么要设置:后端服务默认只能看到请求是来自Nginx的IP地址。为了让后端应用能获取到真实的客户端信息(如IP、域名、协议等),必须通过这个指令手动将这些信息添加到转发的请求头中。

  • 最常见的配置:

proxy_set_header Host $host; # 传递原始请求的域名
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 追加代理IP链
proxy_set_header X-Forwarded-Proto $scheme; # 传递原始请求的协议 (http/https)

三、Gzip

1.指令解析

gzip on|off;

  • 作用:Gzip功能的总开关。默认是关闭的(off)。

  • 用法:要使用Gzip,必须首先设置为on

gzip_types <mime_type> ...;

  • 作用:指定需要进行Gzip压缩的文件MIME类型。默认只压缩text/html

  • 为什么要设置:这是Gzip配置中最关键的一步。我们应该只对文本类文件进行压缩。像图片(JPG/PNG)、视频、PDF以及二进制文件通常不应该被Gzip,因为它们本身已经是高度压缩的格式,再次压缩不仅浪费CPU资源,有时甚至可能让文件体积变得更大。

  • 示例gzip_types text/plain application/javascript text/css application/json text/xml;

gzip_comp_level <level>;

  • 作用:设置Gzip的压缩等级,范围是1到9。

  • 权衡:数字越大,压缩比越高(文件被压缩得更小),但消耗的CPU资源也越多。数字越小,压缩比越低,但处理速度更快。通常,设置为4-6是一个比较理想的平衡点,可以在可接受的CPU开销下获得不错的压缩效果。

gzip_min_length <length>;

  • 作用:设置允许压缩的页面的最小字节数。只有当响应体的Content-Length大于这个值时,Nginx才会对其进行压缩。

  • 为什么要设置:对于非常小的文件,Gzip压缩本身带来的开销(CPU计算、添加HTTP头等)可能会超过其节省的带宽。设置一个合理的阈值(如256字节或1k)可以避免对小文件进行无效压缩。

gzip_proxied <off|any|...>;

  • 作用:当Nginx作为反向代理服务器时,根据后端服务器返回的响应头来决定是否对响应进行压缩。

  • 场景:比如后端服务可能已经对某些内容进行了压缩,或者通过Cache-Control头指定了不希望被代理缓存或修改。这个指令让Nginx可以更智能地处理这些来自上游的响应。

  • 常用值

    • off: 不对代理响应进行压缩。

    • any: 无条件对所有代理响应进行压缩。

    • auth: 当响应头中包含Authorization时才压缩。

    • expired, no-cache, no-store, private: 当响应头中包含相应的ExpiresCache-Control指令时,启用压缩。

gzip_vary on|off;

  • 作用:在响应头中添加Vary: Accept-Encoding

  • 为什么要设置:这个头非常重要。它告诉中间的代理缓存服务器(如CDN、公司的缓存代理),对于同一个URL,需要根据客户端的Accept-Encoding头来缓存不同的版本(一个压缩版,一个未压缩版)。如果没有这个头,缓存服务器可能会错误地把一个压缩版本返回给一个不支持Gzip的旧版浏览器,导致页面乱码。

gzip_buffers <number size>;

  • 作用:设置用于存储Gzip压缩结果的缓冲区数量和大小。例如gzip_buffers 16 8k;表示使用16个8KB的内存块。

gzip_http_version <1.0|1.1>;

  • 作用:启用Gzip所需的最低HTTP协议版本。默认是1.1,通常保持这个设置即可。

gzip_disable "MSIE [1-6]\.";

  • 作用:通过正则表达式匹配客户端的User-Agent,对特定的浏览器禁用Gzip功能。

  • 为什么要设置:这是一个历史遗留选项,主要用于兼容一些古老的、对Gzip支持有问题的浏览器(如IE6)。

四、案例部署

1.前端文件存放

2.修改配置文件

在nginx.conf主配置文件添加模块化语句

vim /usr/local/nginx/conf/conf.d/nginx_demo.conf

在nginx_demo.conf里面填写下面的配置代码

server {# 1. 监听端口listen 80;# 2. 绑定的域名,可以是IP地址或 localhostserver_name hutao; # 或者填写您服务器的 IP 地址# 3. 前端项目静态文件根目录root /usr/local/nginx/html/dist;# 4. 默认首页文件index index.html index.htm;# 5. 前端路由与静态资源处理location / {try_files $uri $uri/ /index.html;}# 6. 后端 API 接口反向代理location /api/ {# 代理的目标地址# 当 proxy_pass 的地址带有 URI 路径时 (例如末尾有 /): Nginx 会将 location 匹配的路径部分剔除,然后将剩余部分拼接到 proxy_pass 的地址上。# 当 proxy_pass 的地址不带 URI 路径时 (例如末尾没有 /): Nginx 会将 location 匹配的完整路径直接拼接到 proxy_pass 的地址上proxy_pass http://127.0.0.1:8090;# 7. 设置请求头proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;# 8. (可选) 增加超时时间proxy_connect_timeout 60s;proxy_read_timeout 60s;}# 9. (可选) 错误页面配置error_page   500 502 503 504  /50x.html;location = /50x.html {root   /usr/local/nginx/html; # Nginx默认错误页面的存放路径}
}
3./的注意事项

五、SSI

1.基本介绍

理解为就是将多个HTML文件拼接到一起,变成一个逻辑上的HTML页面。如何不是对性能追求极致,个人认为用不上它,但是如果请求数量比较多的时候还是有用的。

2.总结
  • 如果您在做一个纯粹的、内部使用的、不需要被搜索引擎收录的应用,或者是一个现代的单页面应用(SPA),那么使用 JavaScript 动态加载组件是完全正确且高效的。

  • 但如果您在做一个面向公众的、内容型的、SEO 和用户体验至关重要的网站,那么使用 Nginx SSI 这种服务器端拼接技术,确保一次性给到客户端完整内容,就绝不是多此一举,而是保证项目成功的基石。

六、文件同步

如果使用SSI技术同时nginx多集群部署后,有可能会存在文件不一致情况,故需要设置文件同步策略。

yum install -y rsync

vim /etc/rsyncd.conf

# /etc/rsyncd.conf
# 全局配置
uid = root
gid = root
use chroot = no
max connections = 10
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid

# 定义一个名为 'www' 的同步模块
[www]
path = /www/      # 数据实际存放的路径
read only = no    # 设置为 no,允许客户端写入数据
auth users = sgg  # 授权访问的用户名,可以自定义
secrets file = /etc/rsyncd.passwd # 存放用户名和密码的文件

# 格式: username:password
echo "sgg:111" > /etc/rsyncd.passwd

chmod 600 /etc/rsyncd.passwd

rsync --daemon

echo "111" > /etc/rsyncd.passwd.client
chmod 600 /etc/rsyncd.passwd.client

rsync -avz --delete --password-file=/etc/rsyncd.passwd.client /usr/local/nginx/html/ sgg@192.168.44.105::www

yum install -y automake

wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

tar -xvf inotify-tools-3.14.tar.gz

cd inotify-tools-3.14

./configure --prefix=/usr/local/inotify

make && make install

#!/bin/bash

MONITOR_DIR="/usr/local/nginx/html/"
TARGET_HOST="192.168.44.105"
TARGET_MODULE="www"
RSYNC_USER="sgg"
CLIENT_PASSWD_FILE="/etc/rsyncd.passwd.client"

/usr/local/inotify/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' \
-e close_write,modify,delete,create,attrib,move ${MONITOR_DIR} | while read file
do
# 这里的 -az 等同于 -avz,但省略了 -v
rsync -az --delete --password-file=${CLIENT_PASSWD_FILE} ${MONITOR_DIR} ${RSYNC_USER}@${TARGET_HOST}::${TARGET_MODULE}
echo "${file} was synced to ${TARGET_HOST} at $(date)" >> /var/log/rsync_realtime.log
done

chmod +x realtime_sync.sh
nohup ./realtime_sync.sh &  # 使用nohup让它在后台持续运行


文章转载自:

http://PC0ylMSL.ycgrL.cn
http://PF5RcWB4.ycgrL.cn
http://tX2tdGIQ.ycgrL.cn
http://3GBrpbO2.ycgrL.cn
http://V2AzygyJ.ycgrL.cn
http://OwRbyxRS.ycgrL.cn
http://skqW3iQX.ycgrL.cn
http://Q3vj0Mgi.ycgrL.cn
http://tpX0STHq.ycgrL.cn
http://jpRSXVYg.ycgrL.cn
http://58Q1ukt6.ycgrL.cn
http://6nOI9oZY.ycgrL.cn
http://UHAEB3R8.ycgrL.cn
http://mcOPNbBQ.ycgrL.cn
http://SAm6kbQD.ycgrL.cn
http://YSiFshz2.ycgrL.cn
http://5pARyg2K.ycgrL.cn
http://wuffATIu.ycgrL.cn
http://FytdGxC1.ycgrL.cn
http://lDXi3oWm.ycgrL.cn
http://a61amoV8.ycgrL.cn
http://GGQ2tLEb.ycgrL.cn
http://KyHrANI6.ycgrL.cn
http://Iz7jtVVO.ycgrL.cn
http://bockdZR3.ycgrL.cn
http://39r1Amqy.ycgrL.cn
http://HHy4Smdt.ycgrL.cn
http://jQlswasy.ycgrL.cn
http://E5MM96ZR.ycgrL.cn
http://7vB8Bgbr.ycgrL.cn
http://www.dtcms.com/a/372886.html

相关文章:

  • LangChain RetrievalQA
  • MybatisPlus开启多租户三步快速集成
  • 现代Web应用前后端架构设计与Python实战
  • YOLO介绍(1)
  • 【javaSE】String类
  • 9.渗透-.Linux基础命令(一)(有vi编辑器)
  • LeetCode - LCR 179. 查找总价格为目标值的两个商品
  • ArcGIS Pro 遇到严重的应用程序错误而无法启动
  • 轻松Linux-9.进程间通信
  • 20250908的学习笔记
  • Golang 与 gRPC
  • shareId 的产生与传递链路
  • Go语言实战案例-开发一个JSON格式校验工具
  • AI技术架构与GEO算法原理如何重塑搜索引擎可见性
  • 【AI测试前沿】谷歌Fuzzing安全测试Go语言指南
  • 佰力博检测与您探讨薄膜样品如何测介电常数?
  • jsBridge接入流程
  • TFS-2018《On the convergence of the sparse possibilistic c-means algorithm》
  • ArrayList中的源码解析
  • 详细解析SparkStreaming和Kafka集成的两种方式的区别和优劣
  • 大数据Spark(六十三):RDD-Resilient Distributed Dataset
  • 云原生TodoList Demo 项目,验证云原生核心特性
  • C语言爬虫开发:常见错误与优化方案
  • Linux 应急响应实操 Checklist
  • 【PCIe EP 设备入门学习专栏 -- 8.2.3 Local Bus Controller (LBC) 详细介绍】
  • 将基于 Oracle JDK 17 开发的 Spring Boot 3.2.12 项目迁移到 OpenJDK 17 环境
  • Vue的计算属性
  • Redis 非缓存核心场景及实例说明
  • 食品罐头(铝罐)表面缺陷数据集:8k+图像,4类,yolo标注
  • 云计算系统安全