上一篇 下一篇 分享链接 返回 返回顶部

进程网络连接异常如何定位?从连接状态、端口到防火墙逐层排查

发布人:Minchunlin 发布时间:2026-10-04 11:36 阅读量:3

进程网络连接异常通常不会只表现为“网络慢”。可能是进程根本没有监听端口、连接卡在 SYN-SENT,也可能是 DNS 解析慢、链路丢包、服务器负载过高,或 TCP 已建立但应用迟迟不返回数据。定位时要先确定影响范围,再按照进程与连接状态、端口监听、本地网络、DNS、路由与丢包、防火墙、服务器负载和应用响应逐层排查。

Linux进程网络连接问题怎么排查,建议遵循“先低风险观察,再做针对性验证”的顺序:先记录进程 PID、目标地址和端口,确认是单个进程、单个目标还是整台主机受影响;随后用 ss 查看连接状态和监听端口,再测试本地网卡、DNS、路由和丢包,最后结合防火墙规则、服务器资源和应用耗时确定根因。修复后不能只看一次请求成功,还要重复验证连接建立、数据返回和错误率是否恢复。

开篇排查方法概述配图

一、先确认症状和影响范围

排查前先收集四项信息:

  • 异常进程的 PID、启动用户和实际运行环境。
  • 目标域名或 IP、目标端口以及使用的协议。
  • 异常开始时间、持续时间和是否可以稳定复现。
  • 是连接失败、连接建立慢、响应慢,还是连接建立后频繁断开。

如果可以登录服务器,先执行以下命令。示例中的 1234、example.com 和 443 需要替换为实际值。

ps -o pid,ppid,user,stat,cmd -p 1234
sudo ss -antp | grep -E 'pid=1234,'
ip route get <目标IP>

根据影响范围可以先做一个分支判断:

现象优先怀疑方向下一步
只有一个进程异常,其他进程正常进程配置、连接池、文件描述符、进程网络命名空间检查 PID 对应的 socket 和进程限制
同一目标端口对所有进程都失败端口监听、路由、防火墙、远端服务检查监听状态并测试 TCP 建连
多个目标都变慢本地网络、DNS、网卡、系统负载检查网卡统计、解析耗时和系统资源
只有域名访问异常,直接访问 IP 正常DNS 或 IPv4/IPv6 选择对比 getent、dig、curl -4 和 curl -6
TCP 已建立但应用响应慢服务器负载、线程池、数据库或应用处理对比连接耗时和首字节耗时,查看应用日志
连接立即被拒绝无监听、端口未开放或主动拒绝检查监听端口和防火墙 reject 规则
连接长时间超时丢包、路由不可达、防火墙丢弃或远端无响应检查路由、端到端丢包和规则计数

不要一开始就重启服务、清空防火墙规则或修改路由。先保留现场,尤其要记录异常发生时的连接状态和规则计数。

二、先看进程、连接状态和端口

1. 确认进程是否真的持有连接

ss 属于常见的 iproute2 工具,用于查看 socket。使用 -p 查看进程信息时通常需要 root 权限。

sudo ss -antp
sudo ss -lntp
sudo lsof -nP -a -p 1234 -i

如果只关注某个端口,可以先过滤输出:

sudo ss -antp | grep -E '(:443|pid=1234,)'
sudo lsof -nP -iTCP:443

重点观察以下信息:

  • 本地地址和端口是否符合预期。
  • 远端地址是否解析到了正确的 IP。
  • 连接是否属于目标 PID,而不是同机的其他进程。
  • 同一目标是否出现大量重复连接。
  • 监听地址是 127.0.0.1、具体内网地址,还是 0.0.0.0。

例如,服务只监听 127.0.0.1:8080,从本机访问可能正常,但其他主机无法访问;服务监听 0.0.0.0:8080,则表示它通常会接收本机各网卡上的连接,但是否真正可达仍取决于路由和防火墙。

如果进程运行在容器或独立网络命名空间中,宿主机看到的端口不一定等于进程命名空间中的端口。可以先确认进程是否存在网络命名空间:

readlink /proc/1234/ns/net
sudo nsenter -t 1234 -n ss -antp

2. 根据 TCP 状态判断故障位置

连接状态比单纯的“连接失败”更有定位价值:

TCP 状态典型含义优先检查
LISTEN进程正在等待入站连接监听地址、端口映射、防火墙
SYN-SENT本机发出连接请求,但没有完成握手目标地址、路由、出口防火墙、远端端口
SYN-RECV本机收到握手请求,正在等待对端确认回程路径、本机资源、监听队列和防火墙
ESTABTCP 已建立应用读写、响应时间、丢包和重传
TIME-WAIT主动关闭连接后的正常等待状态短连接数量、临时端口和连接复用
CLOSE-WAIT对端已关闭,本地进程还没有关闭 socket应用异常、连接释放逻辑
FIN-WAIT本地正在等待连接关闭对端关闭流程、网络中断或应用处理
CLOSED连接已经关闭结合日志判断关闭原因

查看整体状态:

sudo ss -s
sudo ss -tan state syn-sent
sudo ss -tan state syn-recv
sudo ss -tan state close-wait
sudo ss -tan state time-wait | tail -n +2 | wc -l

几种常见判断如下:

  • 大量 SYN-SENT:本机请求可能没有得到响应,重点看路由、丢包、出口规则和远端服务。
  • 大量 SYN-RECV:请求已经到达本机,但握手没有完成,检查回包路径、监听队列和本机防火墙。
  • 大量 CLOSE-WAIT:通常不是网络延迟本身,而是进程收到对端关闭后没有及时释放连接。
  • 大量 TIME-WAIT:短连接频繁建立和关闭时可以是正常现象,不能仅凭数量判定故障;需要结合临时端口范围和应用连接复用策略判断。
  • 大量 ESTAB 但请求仍超时:TCP 层已经打通,应转向应用处理、线程池、后端依赖和数据读写。

查看进程的文件描述符限制,避免把资源耗尽误判为端口或防火墙问题:

sudo grep -i 'open files' /proc/1234/limits
cat /proc/sys/net/ipv4/ip_local_port_range

3. 区分拒绝、超时和重置

使用 TCP 探测可以快速确认端口是否能够建立连接:

nc -vz -w 3 <目标IP或域名> <端口>

不同结果的含义不同:

  • succeeded:TCP 三次握手成功,只能说明端口可建立连接,不能证明应用响应正常。
  • Connection refused:目标主机通常可达,但该端口没有监听,或有设备主动拒绝连接。
  • timed out:可能是路由不可达、数据包丢失、防火墙丢弃、远端主机无响应,也可能是中间设备静默过滤。
  • reset:连接被一方主动重置,可能来自应用、内核、负载设备或防火墙。

若本机端口监听正常,但外部访问仍被拒绝,继续检查监听地址、网络命名空间和防火墙,而不要只重启进程。

三、检查本地网络和 DNS

1. 检查网卡、地址和默认路由

先确认网卡没有明显的错误或丢包:

ip -br addr
ip route
ip -s link

重点关注目标网卡的 RX errors、TX errors、dropped、overruns 等计数。计数持续增长时,可能存在网卡、驱动、链路协商或本机队列问题,但单次计数不为零并不一定意味着当前故障。

查询访问某个目标实际使用的路由:

ip route get <目标IP>

输出中应确认:

  • 使用的出口网卡是否正确。
  • 源地址是否符合预期。
  • 下一跳是否存在。
  • 访问 IPv4 和 IPv6 时是否选择了不同路径。

测试本机到默认网关的连通性:

ping -c 20 -W 1 <默认网关IP>

如果到网关就出现明显丢包或延迟抖动,应先处理本地链路或网卡问题。若网关稳定、远端目标异常,再继续检查路由和中间链路。

需要注意,ICMP 可能被禁用或限速。ping 失败不能单独证明 TCP 端口不可达,必须结合 nc、curl 或实际业务协议测试。

2. 分辨 DNS 慢和连接慢

先看系统实际采用的解析结果:

getent ahosts example.com
cat /etc/resolv.conf

在使用 systemd-resolved 的系统上,还可以执行:

resolvectl status
resolvectl query example.com

使用 dig 观察解析时间和返回记录:

dig +noall +answer +stats example.com A
dig +noall +answer +stats example.com AAAA

如果 dig 查询耗时明显增加,或者不同查询得到的地址差异很大,优先检查 DNS 服务器可达性、解析配置和域名记录。若解析很快,但 curl 的连接阶段很慢,问题就不一定在 DNS。

对比 IPv4 和 IPv6:

curl -4 -sS -o /dev/null -w 'ipv4 dns=%{time_namelookup}s connect=%{time_connect}s total=%{time_total}s\n' \
  --connect-timeout 3 --max-time 10 https://example.com/

curl -6 -sS -o /dev/null -w 'ipv6 dns=%{time_namelookup}s connect=%{time_connect}s total=%{time_total}s\n' \
  --connect-timeout 3 --max-time 10 https://example.com/

如果 IPv4 能快速完成而 IPv6 长时间等待,可能是 IPv6 路由或服务端 IPv6 配置异常;如果两者解析结果都正常但连接阶段慢,应继续检查路由、丢包和防火墙。仅修改 /etc/resolv.conf 作为临时操作可能会被网络管理服务覆盖,不应在没有确认配置归属前直接改写。

四、用路由和丢包定位网络路径

1. 做端到端测试

先对目标 IP 做多次测试,而不是只执行一次 ping:

ping -c 30 -W 1 <目标IP>

观察平均延迟、最大延迟和丢包比例。参考判断方式如下:

  • 延迟稳定但 TCP 连接失败:更偏向端口监听、访问控制或防火墙。
  • 平均延迟不高但最大延迟偶发升高:可能存在队列拥塞、链路抖动或突发负载。
  • 持续丢包且 TCP 重传增加:优先检查链路、路由和中间设备。
  • ping 丢包但 TCP 业务正常:可能是 ICMP 限速,不能直接当作业务丢包。

2. 查看路径上的变化

可以使用 TCP 探测让路径测试更接近实际业务端口:

sudo traceroute -n -T -p <端口> <目标IP>

如果系统没有 traceroute,可以尝试:

tracepath -n <目标IP>

安装并具备条件时,也可以执行多次统计:

mtr -rwzc 30 <目标IP>

路由工具的判断要看“从某一跳开始,后续多跳以及最终目标是否持续丢包”:

  • 只有中间某一跳显示丢包,而后续节点和最终目标正常,通常是该节点限制探测报文响应,不一定影响业务。
  • 从某一跳开始,后续所有节点和最终目标都出现类似丢包或延迟升高,才更值得怀疑该段路径。
  • 最终目标延迟高,但中间跳正常,可能是目标主机负载、目标侧限速或目标侧响应策略。
  • traceroute 只能帮助观察路径和探测报文的响应,不能证明应用请求的处理时间。

3. 查看 TCP 重传

对已经建立的连接,可以查看 TCP 统计信息:

sudo ss -ti
nstat -az | grep -Ei 'Retrans|Timeout'

ss -ti 中如果看到重传计数、重传超时或拥塞窗口反复变化,应把连接质量和应用响应慢区分开。必要时在短时间内抓取指定目标和端口的报文:

sudo tcpdump -ni any host <目标IP> and tcp port <端口> -c 100

抓包可能包含业务地址、请求元数据甚至未加密内容,应限定时间和过滤条件,并按所在环境的审计要求保存。可以重点观察:

  • SYN 是否发出、SYN-ACK 是否返回。
  • 同一序号是否反复重传。
  • 服务端是否已经发送数据,而客户端没有及时确认。
  • 连接是否被 RST 重置。

如果握手报文往返正常、数据包也没有明显重传,但应用仍然迟迟没有响应,就不要继续把主要精力放在网络路径上。

五、检查防火墙和端口访问控制

防火墙导致的表现通常有两类:主动拒绝会较快返回错误,丢弃规则则常表现为连接超时。先确认系统实际使用的防火墙管理方式,不要同时修改多个规则系统。

使用 firewalld 的系统:

sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=<实际区域> --list-all

使用 nftables 的系统:

sudo nft list ruleset -a

仍使用 iptables 规则的系统可以查看:

sudo iptables -L -n -v --line-numbers
sudo ip6tables -L -n -v --line-numbers

检查时关注:

  • 目标端口是否被允许。
  • 规则匹配的是正确的网卡、源地址、目标地址和协议。
  • IPv4 和 IPv6 是否使用了不同规则。
  • 规则计数器在复现请求时是否增长。
  • 默认策略是 ACCEPT 还是 DROP。
  • 连接跟踪是否异常,是否存在过度严格的并发限制。

不要使用 iptables -F、直接停止防火墙服务或清空 nftables 规则来“验证”问题。这样可能暴露其他端口,也可能导致远程管理连接中断。

如果必须做临时验证,应满足以下前提:已经保存当前规则、具备控制台或带外登录能力、明确影响范围,并只开放指定来源和端口。以 firewalld 为例,可以先备份当前可见配置:

sudo firewall-cmd --list-all-zones > /root/firewalld-before-$(date +%F-%H%M%S).txt

然后只做运行时、限定来源的临时规则测试。以下命令中的区域、客户端 IP 和端口必须替换为实际值:

sudo firewall-cmd --zone=<实际区域> \
  --add-rich-rule='rule family="ipv4" source address="<客户端IP>" port port="<端口>" protocol="tcp" accept'

sudo firewall-cmd --zone=<实际区域> \
  --query-rich-rule='rule family="ipv4" source address="<客户端IP>" port port="<端口>" protocol="tcp" accept'

验证完成后使用完全相同的规则内容回滚:

sudo firewall-cmd --zone=<实际区域> \
  --remove-rich-rule='rule family="ipv4" source address="<客户端IP>" port port="<端口>" protocol="tcp" accept'

该方式只改变当前运行时配置,不要在根因尚未确认时执行永久化操作。若测试后仍然无法连接,应撤销临时规则并继续检查路由、监听端口和远端服务,而不是持续扩大放行范围。

六、检查服务器负载和应用响应

1. 判断服务器是否有资源瓶颈

如果 TCP 已经建立,但响应越来越慢,应在服务端同时观察 CPU、内存、I/O 和进程线程:

uptime
vmstat 1 5
free -h
df -h

如果系统安装了 sysstat,可以进一步执行:

mpstat 1 5
iostat -xz 1 3
pidstat -p 1234 -t 1 5

判断重点包括:

  • CPU 使用率持续接近上限,或单个线程长期占满 CPU。
  • vmstat 中运行队列明显变长,系统频繁等待 CPU。
  • iowait 较高,说明请求可能卡在磁盘或其他 I/O。
  • 可用内存不足并伴随 swap 活跃。
  • 进程线程数、文件描述符或连接数接近限制。
  • 服务日志中出现线程池耗尽、连接池耗尽、后端超时等信息。

如果使用 systemd 管理服务,可以按异常时间查看日志:

sudo journalctl -u <服务名> --since "10 minutes ago" --no-pager -n 100

2. 用响应分段确认慢在哪里

对于 HTTP 或 HTTPS 服务,可以让 curl 输出各阶段耗时:

curl -sS -o /dev/null \
  -w 'dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s first_byte=%{time_starttransfer}s total=%{time_total}s\n' \
  --connect-timeout 3 --max-time 15 \
  https://example.com/

可以这样解读:

  • time_namelookup 高:DNS 解析慢。
  • time_connect 高:TCP 建连慢,检查路由、丢包、端口和防火墙。
  • time_appconnect 高:通常是 TLS 握手阶段慢,需要结合连接质量和服务端加密处理判断。
  • time_starttransfer 明显高,但 time_connect 正常:请求已经到达应用,服务端处理或后端依赖较慢。
  • time_total 高而首字节时间正常:可能是响应传输、连接复用或后续数据读取阶段存在问题。

一次成功请求不能代表故障恢复。应在相同目标、相同端口和相近业务条件下连续执行多次,并将结果与故障前或正常节点对比。对于非 HTTP 协议,至少分别记录“TCP 建连耗时”和“应用收到请求后的响应耗时”,不能用 nc 建连成功代替业务成功。

六、检查服务器负载和应用响应配图

七、用问题树收敛根因

完成上述检查后,可以按以下路径缩小范围:

  1. 进程是否存在且持有目标连接?

如果 PID 不存在、连接属于其他进程或进程没有预期 socket,先检查进程启动参数、配置和网络命名空间。

  1. 服务端是否监听正确端口和地址?

没有 LISTEN,或只监听本地回环地址,优先修正服务配置。修改配置前应保存原文件,并准备按原值回滚。

  1. TCP 是否能完成握手?

SYN-SENT、连接超时或端口拒绝,检查目标地址、ip route get、路由路径、端口访问控制和防火墙。

  1. 解析结果是否正确且稳定?

域名解析慢、解析到不可达地址,或 IPv4/IPv6 表现不同,应检查解析配置和对应协议栈路径。

  1. 连接建立后是否有重传或延迟?

有重传时继续检查链路和路径;没有重传但首字节慢,转向服务端负载、线程池、连接池和应用日志。

  1. 修复后是否恢复了完整链路?

重新确认监听端口、连接状态、TCP 建连、应用首字节和完整响应,而不是只确认某条规则或某个命令返回成功。

八、修复后的验证和复发监控

修复完成后,建议按同一顺序复测:

sudo ss -lntp | grep -E ':(<端口>)\b'
nc -vz -w 3 <目标IP或域名> <端口>
curl -sS -o /dev/null \
  -w 'connect=%{time_connect}s first_byte=%{time_starttransfer}s total=%{time_total}s code=%{http_code}\n' \
  --connect-timeout 3 --max-time 15 \
  https://example.com/

同时再次观察:

sudo ss -s
sudo ss -ti
ip -s link

验证结果应至少满足以下条件:

  • 目标进程仍在运行,并持有预期连接。
  • 监听地址和端口没有因重启或配置加载而改变。
  • TCP 建连不再持续卡在 SYN-SENT。
  • 连接重传、丢包和异常重置没有继续增长。
  • DNS、连接、首字节和完整响应耗时回到可接受范围。
  • 防火墙临时规则已经按计划保留或回滚,未遗留过度放行。

为避免问题再次发生,应持续记录进程连接状态、CLOSE-WAIT 和 TIME-WAIT 数量、TCP 重传、端口连接失败率、DNS 耗时、TCP 建连耗时、应用首字节耗时以及 CPU、内存和 I/O 指标。下次出现异常时,将这些指标与正常时段对比,通常比单独查看一条错误日志更容易判断问题究竟发生在进程、端口、网络路径、防火墙还是应用处理阶段。

目录结构
全文