ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Nginx连接数监控:从基础原理到实战排查的完整指南

2026/8/6 4:34:52 拓冰建站 浏览量
Nginx连接数监控:从基础原理到实战排查的完整指南 1. 项目概述为什么我们需要关注Nginx连接数在运维和开发的实际工作中Nginx的状态监控就像汽车的仪表盘而连接数则是其中最关键的几个仪表之一。想象一下你负责的电商网站在大促期间突然响应变慢页面加载时间从几百毫秒飙升到几秒用户开始抱怨。这时候你的第一反应是什么是代码有Bug还是数据库慢了很多时候问题的根源可能在于流量洪峰压垮了你的Web服务器而连接数就是最直观的“压力表”。它直接反映了Nginx当前正在处理的客户端请求数量包括正在等待的和正在响应的。一个异常飙升的活跃连接数往往意味着服务器正在过载或者后端应用出现了阻塞。我遇到过不少案例团队花了大量时间排查应用日志和数据库性能最后才发现是Nginx的worker_connections参数配置过低导致连接池迅速耗尽新的请求被直接丢弃。因此掌握查看Nginx连接数的方法不仅仅是执行几条命令更是构建系统可观测性、进行容量规划和故障快速定位的基础技能。无论是日常巡检、性能调优还是突发的线上故障应急它都是你工具箱里必备的“听诊器”。接下来我会结合多年实战经验为你拆解几种核心方法从内置状态模块到系统级命令让你不仅能看懂数字更能理解数字背后的故事。2. 核心方法一使用Nginx内置的ngx_http_stub_status_module模块这是Nginx官方提供的、最标准也是最常用的连接数查看方法。它通过一个简单的HTTP接口暴露了Nginx进程的关键状态信息。但首先你需要确认你的Nginx编译安装时包含了这个模块。2.1 模块检查与启用对于大多数通过包管理器如yum、apt安装的Nginx该模块通常是默认包含的。你可以通过以下命令快速验证nginx -V 21 | grep -o with-http_stub_status_module如果输出with-http_stub_status_module则说明模块已存在。如果没有输出你可能需要重新编译Nginx并加入--with-http_stub_status_module参数或者寻找包含此模块的发行版。启用该模块需要在Nginx的配置文件中通常是nginx.conf或/etc/nginx/conf.d/下的某个文件添加一个location块。我个人的习惯是单独创建一个配置文件比如/etc/nginx/conf.d/status.conf这样管理起来更清晰也避免污染主业务配置。server { listen 8080; # 建议使用一个内部端口不要暴露在公网 server_name localhost; # 或你的内网IP location /nginx_status { stub_status on; access_log off; # 状态页面访问通常不需要记录日志 allow 192.168.1.0/24; # 只允许特定内网IP段访问这是安全关键 allow 127.0.0.1; deny all; # 拒绝其他所有访问 # 如果需要有基础认证可以加上 # auth_basic Nginx Status; # auth_basic_user_file /etc/nginx/.htpasswd; } }注意安全是重中之重绝对不要将stub_status页面暴露在公网。它虽然不包含敏感业务数据但攻击者可以通过它了解你服务器的负载状况为后续攻击做准备。务必使用allow/deny指令进行IP限制或结合防火墙规则。配置完成后执行nginx -t测试配置语法无误后通过nginx -s reload重载配置。2.2 状态页面解读与深度分析现在访问http://your-server-internal-ip:8080/nginx_status你会看到类似下面的信息Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106这几行数字就是宝藏我们来逐一解码Active connections当前活跃的客户端连接数。这是最需要关注的指标它直接反映了Nginx的实时负载压力。这个数字应该与你配置的worker_connections在events块中进行比较。如果Active connections长期接近worker_connections的上限就意味着连接池即将耗尽新请求会被拒绝必须立即扩容或调优。accepts, handled, requestsaccepts自Nginx启动以来已经接受的客户端连接总数。handled成功处理的连接总数。通常accepts和handled是相等的如果两者出现差值说明有些连接被直接关闭了例如在未分配工作进程时。requests自Nginx启动以来客户端总共发起的请求数量。这是一个累计值可以用来计算平均每个连接处理的请求数requests / handled即“连接复用率”。在HTTP/1.1 Keep-Alive开启的情况下这个比值越高说明连接复用效果越好服务器建立和断开连接的开销越小。Reading, Writing, Waiting这三个是对Active connections的进一步细分是分析服务器当前工作状态的“显微镜”。Reading正在读取请求头的连接数。如果这个值异常高可能意味着客户端网络很慢或者正在上传大文件。Writing正在向客户端发送响应的连接数。这是服务器“正在工作”的主要体现。如果Writing数量很多且持续可能意味着后端应用响应慢或者正在返回大量数据。Waiting处于空闲状态正在等待后续请求的持久连接Keep-Alive数。这是健康状态的标志。在连接复用场景下一定数量的Waiting连接是正常的它们避免了频繁建立新连接的开销。但如果Waiting连接数过多而Reading和Writing很少可能意味着你的keepalive_timeout设置得过长导致连接资源被闲置占用。实操心得不要只看Active connections的绝对值。我习惯将Reading、Writing、Waiting的比例作为一个健康度指标。在一个处理API请求的服务上理想状态下Writing占主导Waiting维持一定比例Reading很少。如果发现Reading长期偏高我就会去检查是否有慢速客户端攻击或者调整client_header_timeout。3. 核心方法二利用操作系统网络工具进行宏观分析当Nginx的stub_status模块不可用或者你需要从更底层、更全局的视角来审视连接情况时操作系统的网络工具就派上用场了。它们能告诉你系统层面所有与Nginx端口相关的连接包括一些处于异常状态的连接如TIME_WAIT,CLOSE_WAIT这些信息在Nginx状态页面上是看不到的。3.1netstat命令的经典用法netstat是一个历史悠久的网络统计工具虽然在新系统中逐渐被ss命令取代但其输出格式对很多人来说更直观。# 查看所有与Nginx监听端口例如80和443相关的连接 netstat -anp | grep -E ‘:(80|443)’ | grep ESTABLISHED # 更详细的统计按状态分类 netstat -ant | awk ‘/^tcp/ {print $6}’ | sort | uniq -c | sort -rn第一条命令可以快速查看当前正在活动的业务连接数。第二条命令则是一个经典技巧它能统计出所有TCP连接的各种状态数量输出类似125 ESTABLISHED 32 TIME_WAIT 5 LISTEN 2 CLOSE_WAIT这对于发现连接泄漏问题非常有用。例如如果TIME_WAIT状态连接堆积如山成千上万可能会耗尽本地端口资源这通常需要调整内核参数net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle注意tcp_tw_recycle在较新内核中已废弃需谨慎使用。3.2ss命令更现代、更快速的替代方案ssSocket Statistics是netstat的替代品来自iproute2工具包速度更快信息更详细。# 查看所有连接到Nginx工作进程的端口 ss -tlnp sport :80 or sport :443 # 查看Nginx进程建立的所有连接更精确 # 首先获取Nginx master进程的PID通常worker进程是它的子进程 sudo ss -tnp dst :80 or dst :443 | grep nginx # 按状态快速统计 ss -ant | grep -v ‘State’ | awk ‘{print $1}’ | sort | uniq -c为什么更推荐ss在连接数非常高的服务器上例如超过数万netstat可能会因为遍历/proc/net/tcp文件而显得缓慢消耗更多CPU。而ss直接从内核获取信息效率极高。在应急排查时使用ss能更快地得到结果。3.3 通过/proc文件系统直接读取Linux万物皆文件连接信息也记录在/proc文件系统中。Nginx每个工作进程worker process的连接信息可以在其对应的/proc/[pid]/fd/目录下窥见一斑每个socket连接对应一个文件描述符。但更直接的是查看全局的TCP信息# 查看所有TCP连接并过滤出目标端口是80或443的 cat /proc/net/tcp | awk ‘{print $2, $3}’ | grep ‘:0050\|:01BB’ # 0050是80的十六进制01BB是443的十六进制这种方法比较原始输出是十六进制可读性差一般不用于手动检查但它是很多监控代理如Zabbix agent, Telegraf采集数据的基础方式因为直接读取文件开销极小。实操心得我通常将ss命令作为日常巡检和故障排查的首选。特别是ss -tnp可以同时看到连接和对应的进程名在排查“哪个进程占用了大量连接”时非常高效。记得结合watch命令进行动态观察watch -n 1 ‘ss -tnp dst :80 | grep nginx | wc -l’可以每秒刷新一次Nginx 80端口的活跃连接数在压测或故障时非常直观。4. 核心方法三解析Nginx访问日志进行间接推断日志是历史的记录虽然不能反映实时瞬间的连接数但它是分析连接趋势、识别异常客户端和复盘历史问题的宝贵资料。通过分析特定时间窗口内的日志条目我们可以推算出当时的并发请求情况这近似于该时间段内的平均活跃连接数。4.1 使用awk进行快速时间窗口分析假设你的Nginx访问日志格式是默认的combined格式并且时间戳在第四列。我们可以用awk来统计每秒的请求数这在一定程度上能反映连接的并发度。# 统计最近1分钟内每秒的请求数量观察波峰 awk -vDatedate -d’-1 min’ [%d/%b/%Y:%H:%M:%S ‘$4 Date {print $4}’ /var/log/nginx/access.log | cut -d[ -f2 | cut -d] -f1 | awk -F: ‘{print $1“:”$2“:”$3}’ | sort | uniq -c | sort -rn | head -20这个命令看起来复杂拆解一下date -d’-1 min’生成一分钟前的时间。awk ‘$4 Date’筛选出日志时间戳在一分钟内的记录。后续的cut和awk用于提取出精确到秒的时间戳如02/Aug/2023:15:30:45。sort | uniq -c统计每秒出现的次数即每秒请求数。sort -rn | head -20列出请求数最高的前20秒。4.2 使用专业日志分析工具GoAccess对于长期、深入的日志分析命令行工具可能力不从心。我强烈推荐使用GoAccess。它可以生成实时的、交互式的HTML报告从连接访问者维度提供丰富的洞察。安装GoAccess后你可以这样使用# 生成一个HTML报告 zcat /var/log/nginx/access.log.*.gz | goaccess -a -o /path/to/report.html # 或者实时分析当前日志文件 tail -f /var/log/nginx/access.log | goaccess -a -o /path/to/report.html --real-time-html在GoAccess的报告中你可以清晰地看到独立访客数近似于同一时间段的并发连接用户数。请求频率每秒/每分钟/每小时的请求数图表直接对应了连接的繁忙程度。客户端IP排名迅速找出哪些IP建立了过多的连接可能是爬虫、攻击源或者有问题的客户端。实操心得日志分析的价值在于“事后诸葛亮”和“趋势发现”。我曾经通过分析GoAccess报告发现每天凌晨3点总有几个固定的IP产生大量请求但响应状态码都是499客户端提前关闭连接。顺藤摸瓜发现是一个配置错误的内部定时任务在疯狂重试。因此将日志分析与实时连接监控结合才能构建完整的监控视野。对于生产环境建议将Nginx日志实时接入ELKElasticsearch, Logstash, Kibana或Grafana Loki这类日志平台进行更强大的聚合和告警。5. 核心方法四集成第三方监控系统实现自动化手动执行命令只适用于临时检查对于7x24小时运行的业务系统我们需要自动化的、可视化的监控方案。将Nginx连接数指标接入Prometheus这样的监控系统是当前业界的标准做法。5.1 使用Nginx Exporter暴露指标Nginx本身不直接提供Prometheus格式的指标。我们需要一个“翻译官”——nginx-prometheus-exporter。这个exporter会去抓取我们前面配置的stub_status页面的数据并将其转换为Prometheus能够识别的格式。部署方式通常很简单可以下载二进制文件直接运行./nginx-prometheus-exporter -nginx.scrape-urihttp://localhost:8080/nginx_statusExporter默认会在9113端口提供一个/metrics端点。访问这个端点你会看到格式化的指标例如# HELP nginx_connections_active Active client connections # TYPE nginx_connections_active gauge nginx_connections_active 123 # HELP nginx_connections_reading Connections where NGINX is reading request header # TYPE nginx_connections_reading gauge nginx_connections_reading 5 ...5.2 配置Prometheus抓取与Grafana可视化接下来在Prometheus的配置文件prometheus.yml中添加一个针对exporter的抓取任务scrape_configs: - job_name: ‘nginx’ static_configs: - targets: [‘your-nginx-server-ip:9113’] scrape_interval: 15s # 每15秒抓取一次重启Prometheus后它就会开始定期收集Nginx的连接数数据。最后在Grafana中创建一个仪表盘使用PromQL查询语句来绘制图表活跃连接数趋势图nginx_connections_active读写等待连接分布nginx_connections_reading,nginx_connections_writing,nginx_connections_waiting请求率rate(nginx_requests_total[5m])计算每秒请求数你还可以设置告警规则例如当活跃连接数超过worker_connections的80%时触发告警通知。实操心得搭建监控体系初期可能会觉得麻烦但一旦建成它带来的价值是巨大的。除了基础连接数我还建议收集nginx_upexporter自身健康状态和nginx_exporter_scrape_failures_total抓取失败次数等指标。在Grafana面板上我将活跃连接数与服务器CPU、内存使用率、后端应用响应时间放在同一个视图里这样当出现问题时可以一眼看出是网络流量问题、服务器资源问题还是应用代码问题极大提升了故障定位效率。6. 常见问题与排查技巧实录掌握了查看方法更重要的是能解决实际问题。下面是我在多年运维中积累的一些关于Nginx连接数的典型问题场景和排查思路。6.1 连接数异常飙升服务器响应变慢现象通过stub_status或ss命令发现Active connections或Writing连接数突然暴涨服务器负载升高响应时间变长。排查思路区分流量来源首先用ss -tnp dst :80查看这些连接的客户端IP。如果来自少量IP可能是CC攻击或某个失控的客户端。如果来源广泛可能是正常流量高峰或某个热点内容被传播。检查后端健康Nginx连接数高很可能是因为后端应用如PHP-FPM, Tomcat, Node.js处理变慢导致请求堆积在Nginx。立即检查后端应用的监控指标响应时间、错误率、队列长度。分析日志使用tail -f查看Nginx错误日志error.log和访问日志access.log。关注是否有大量502 Bad Gateway或504 Gateway Timeout错误这明确指向后端问题。同时查看访问日志中慢请求可通过$request_time记录的模式。检查系统资源使用top,htop,vmstat 1查看CPU、内存、磁盘I/O和系统负载。确认不是服务器本身资源耗尽。限流与降级如果确定是异常流量立即启用Nginx的限流模块如limit_req_zone进行临时控制并考虑将非核心功能降级。我的一个案例有一次Writing连接数持续高位但后端应用监控正常。最后发现是Nginx配置中proxy_buffering被关闭且一个API接口返回了一个巨大的JSON几十MB导致Nginx必须同步地、缓慢地将数据发送给每一个慢速的移动端客户端占用了大量工作进程。开启proxy_buffering后Nginx可以快速从后端读完响应再异步发送给客户端连接数迅速下降。6.2TIME_WAIT状态连接过多现象使用ss -ant | grep TIME-WAIT | wc -l发现数量极大比如上万有时甚至会影响新连接的建立。原因分析TCP连接关闭时主动关闭方对于Nginx作为反向代理它向后端建立连接时是客户端关闭时可能是主动方会进入TIME_WAIT状态等待2MSLMaximum Segment Lifetime通常为60秒时间以确保网络中残留的数据包已经消失。高并发短连接场景下此状态连接会快速积累。解决方案与权衡启用端口复用修改内核参数这是最常用的方法。sysctl -w net.ipv4.tcp_tw_reuse1 # 允许将TIME-WAIT sockets重新用于新的TCP连接 # net.ipv4.tcp_tw_recycle 在较新内核中已废弃不建议使用 sysctl -w net.ipv4.tcp_max_tw_buckets180000 # 增大系统允许的TIME_WAIT数量上限将这些写入/etc/sysctl.conf使其永久生效。优化Nginx与后端连接启用HTTP/1.1的Keep-Alive让Nginx与后端服务器复用连接而不是每次请求都新建连接。这在upstream配置块中设置upstream backend { server 10.0.0.1; keepalive 32; # 保持最多32个空闲连接向上游 } location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection “”; }调整Nginx连接关闭行为可以尝试调整keepalive_timeout和keepalive_requests让客户端连接更合理地复用和关闭。注意盲目调整tcp_tw_reuse等参数可能有风险特别是在负载均衡器或NAT环境下。修改前最好在测试环境验证并充分理解其含义。6.3 Nginx状态页面显示accepts与handled数值不相等现象在stub_status输出中accepts和handled两个数字有微小差距。深度解析这通常不是大问题但值得理解其含义。accepts代表从内核接受accept的连接数handled代表被Nginx工作进程成功处理的连接数。两者不相等意味着有些连接在从内核“接受”到被工作进程“处理”这个极短的空窗期内就被关闭了。可能的原因有客户端在完成TCP三次握手后立即发送了RST包断开连接可能是端口扫描行为或客户端异常。在连接被放入监听队列listen queue后但在被worker进程accept之前客户端超时关闭。如果这个差值accepts - handled持续且显著增大则需要关注netstat -s | grep listen中的times the listen queue of a socket overflowed监听队列溢出次数是否在增加。这可能意味着瞬间的并发连接请求超过了net.core.somaxconn和Nginxlisten指令中backlog参数的限制需要考虑适当调大这些参数。排查清单速查表问题现象可能原因排查命令/位置解决思路活跃连接数(Active)持续高位1. 真实流量大2. 后端应用慢3. 客户端慢如大文件上传下载1.ss -tnp看连接分布2. 检查后端监控3. 查看Nginx$request_time日志1. 扩容2. 优化后端3. 调整proxy_buffering,send_timeoutWriting连接数特别高1. 后端响应慢Nginx在“等”2. 响应体巨大发送慢3. 客户端网络差1. 后端应用监控2. 检查接口返回数据大小3. Nginx错误日志1. 优化后端2. 开启Gzip压缩分页3. 调整proxy_send_timeoutWaiting连接数异常多keepalive_timeout设置过长查看Nginx配置适当调低keepalive_timeout大量TIME_WAIT连接高并发短连接TCP连接频繁建立关闭ss -ant | grep TIME-WAIT | wc -l1. 调内核参数(tcp_tw_reuse)2. 启用upstream keepalive新建连接被拒绝1.worker_connections耗尽2. 系统文件描述符限制3. 监听队列溢出1. Nginxstub_status2.ulimit -n3.netstat -s | grep listen1. 增加worker_connections2. 增加系统nofile限制3. 增大somaxconn和backlog掌握这些方法后你看待Nginx连接数的视角就从一个个孤立的数字变成了一个动态的、反映系统整体健康状况的仪表盘。真正的能力不在于记住命令而在于当数字异常时能结合上下文快速形成排查假设并验证。这需要你对Nginx工作原理、操作系统网络和业务特性都有一定的理解。建议你在自己的测试环境中模拟不同的场景如使用ab,wrk进行压测或使用tc命令模拟网络延迟观察连接数指标的变化积累第一手的经验。