前言
建立一个连接如下几个阶段
连接阶段
- 资源计划(这个阶段时间长,一般是前端代码导致访问阻塞了)
- 连接开始(这个要查看DNS配置和Nginx相关配置)
- 请求响应(这个要查看Nginx和后端服务的问题)
如图 初始连接的时间特别长 可能原因如下
| 层面 | 具体原因 |
|---|---|
| Nginx 自身配置 | 1. 未启用 TCP 长连接(Keep-Alive),每次请求都重建 TCP 连接; 2. 工作进程(worker_processes)或连接数(worker_connections)不足; 3. 启用了不必要的模块(如 gzip、ssl_session_cache 未配置); 4. DNS 解析慢(Nginx 转发时用域名指向后端,未配置 DNS 缓存)。 |
| 后端服务层面 | 1. 后端服务启动后初始化慢(加载缓存、连接池耗时); 2. 后端服务连接池满(如 Tomcat maxConnections 耗尽),拒绝新连接; 3. 后端服务健康检查失败,Nginx 反复重试无效节点。 |
| 网络层面 | 1. 客户端→Nginx 或 Nginx→后端的网络路由跳转多、延迟高; 2. 防火墙 / 安全组拦截,导致 TCP 握手超时重试; 3. SSL/TLS 握手耗时久(未启用 TLS 复用、未配置会话缓存)。 |
| 其他 | Nginx 日志输出阻塞(如同步写日志到远程服务器)、系统资源不足(CPU / 内存占用高)。 |
排查连接长原因
先排查两个连接的时长
测试 客户端→Nginx 的连接耗时
本地测试连接服务器
1 | curl -o /dev/null -s -w "TCP Connect Time: %{time_connect}s\n" https://api2.xhkjedu.com/ |
测试 Nginx→后端服务 的连接耗时
Nginx所在服务器上测试连接后端
1 | curl -o /dev/null -s -w "TCP Connect Time: %{time_connect}s\n" http://192.168.1.12:3000 |
优化
排查域名映射
在阿里云或其他DNS解析上,查看二级域名解析的IP是不是唯一的,我这最终排查到的竟然是添加了两个解析记录导致的,按理说应该是添加不上的。
启用TCP长连接
启用 TCP 长连接,避免重复握手
1 | # 1. 启用Nginx→后端服务的长连接(关键!) |
必须在server下的配置
1 | client_header_timeout 10s; # 接收请求头超时(推荐5-10s) |
location下配置
1 | # 浏览器-Nginx的长连接 |
前两个是浏览器和Nginx连接的参数
超时时间(keepalive_timeout)越长越好?
不是!设为 120 秒以上会导致 Nginx 占用大量空闲连接,服务器资源浪费,60-90 秒是兼顾 “复用效果” 和 “资源占用” 的最优区间。
请求数(keepalive_requests)越多越好?
不是!超过 500 次后,长连接的稳定性可能下降(比如内存泄漏风险),除非有实际压测数据支撑,否则不建议盲目调大。
Nginx连接数优化
根据服务器 CPU 核心数调整,确保 Nginx 能处理足够的并发连接:
查看Nginx配置连接数
1 | grep -r "worker_connections" /etc/nginx/ |
查看实际使用的连接数
1 | # 统计 80/443 端口各状态连接数(用 ss,推荐) |
输出示例
1 | 256 ESTABLISHED # 已建立的有效连接(正在处理请求) |
优化 SSL(若启用 HTTPS)
1 | server { |
DNS解析优化
如果 upstream 中用域名(如server backend.service.com:8080),Nginx 默认每次转发都会重新解析 DNS,导致延迟。
注意
如果
upstream中使用的是IP,则不用考虑这个配置。
解决方案:
- 优先改用后端服务 IP(彻底避免 DNS 解析)。
- 若必须用域名,配置 Nginx DNS 缓存。
Nginx
1 | http { |