|
|
career-ops 连接超时排查:网络故障定位与修复实战
“career-ops 系统又超时了!”——这大概是运维同学最不想听到的报警之一。连接超时这个问题,说大不大说小不小,但排查起来容易胡子眉毛一把抓。这篇文章来聊聊怎么系统化地搞定它。
## 先说说现象
客户端请求发出去,结果石沉大海,等了半天收到 `Connection timed out` 或 `ETIMEDOUT` 错误。问题出在 TCP 三次握手阶段,数据包没能正常往返。从协议层面看,这属于网络层的问题。
## 常见的坑有哪些
**路由层面不通。** 目标地址的路由条目丢了,或者下一跳设备压根到不了。这种情况大概占 35% 左右。
**端口没监听。** 目标主机的端口没有进程绑定,TCP 握手请求被 RST 包打回来。如果你看到 `Connection refused`,基本就是这个问题。
**防火墙给拦了。** iptables、cloud security group 这些规则如果显式 DROP 了入站流量,问题会比较隐蔽——防火墙静默丢弃不会返回 ICMP 不可达,排查时容易往其他方向猜。
**DNS 解析拉胯。** 用域名连接的话,DNS 超时或返回错误 IP 直接导致连接失败。
**超时时间设太短。** 业务侧配置的超时阈值比实际 RTT 还小,跨地域链路稍微抖一下就超时。
## career-ops 专属的几个场景
职业发展系统有一些自己的特点,以下三种情况特别容易中招:
**认证 token 过期了。** career-ops 用 OAuth2.0,access_token 默认 7200 秒过期。token 一旦失效,后续请求在 TLS 握手阶段就会超时,根本不会给你返回正常的 HTTP 401。验证方法:
```bash
curl -I https://career-ops.internal/oauth/token_info
```
看 `expires_in` 字段,如果变成负数或零,token 已经失效。
**服务注册中心挂了。** career-ops 依赖 Consul 或 etcd 做服务发现。注册中心宕机或网络分区时,客户端根本拿不到目标服务地址,所有请求直接超时。检查命令:
```bash
consul members -status=alive
curl http://consul.internal:8500/v1/health/service/career-ops
```
**健康检查端口被误伤。** career-ops 的 `/healthz` 端点走 8080 端口。这个端口如果被安全组或防火墙拦了,负载均衡器会判定实例不健康并移除,可应用层还在跑着,这时候业务请求就会一直超时。
## 排查步骤
### 第一步:确认网络通不通
```bash
ping -c 4 career-ops.internal
traceroute career-ops.internal # Linux/macOS
tracert career-ops.internal # Windows
```
ping 不通就先搞定路由问题。traceroute 在某跳之后没响应的话,故障就定位在那台设备或后续链路上。
### 第二步:看端口状态
```bash
nc -zv career-ops.internal 443
telnet career-ops.internal 443
netstat -tlnp | grep 8080
ss -tlnp | grep 8080
```
端口在 LISTEN 状态但还是超时?可能是 upstream 配置的问题。
### 第三步:查防火墙
```bash
iptables -L -n -v | grep career-ops
aws ec2 describe-security-groups \
--filters "Name=ip-permission.to-port,Values=443"
```
重点来了:防火墙 DROP 行为不会在目标主机留日志,怀疑是这里的问题时需要结合中间节点抓包判断。
### 第四步:抓包看握手过程
```bash
tcpdump -i eth0 host career-ops.internal and port 443 -w output.pcap
```
看结果:
- SYN 发出去没反应 → 网络层不通
- SYN 一直重传 → 端口被拦了
- 收到 RST → 端口没开放或者策略明确拒绝
### 第五步:验证 DNS
```bash
dig career-ops.internal
nslookup career-ops.internal
cat /etc/hosts | grep career-ops
```
DNS 解析延迟超过 500ms 的话,建议在 `/etc/resolv.conf` 里加个就近的 DNS 服务器。
## 实际案例
### 案例一:防火墙静默丢弃
ping 正常,telnet 端口没响应,连接 5 秒就超时。查了一圈发现目标主机的 iptables 默认策略是 DROP,443 端口没放行。
```bash
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
iptables-save > /etc/iptables/rules.v4
```
### 案例二:超时时间设太短
跨地域场景,中国大陆访问海外实例,实际 RTT 差不多 180ms,但超时配置只有 100ms。
```bash
curl --connect-timeout 5 --max-time 30 https://career-ops.internal/api/status
```
配置文件里也可以改:
```yaml
timeout:
connect: 5000
read: 30000
```
### 案例三:Keepalive 连接复用坑
career-ops 默认启用 HTTP Keep-Alive,upstream 服务端如果主动关了连接而客户端没感知,就会触发 `Connection reset by peer` 或超时。高并发下这个问题特别明显,表现为间歇性超时。
```bash
cat /proc/net/sockstat
```
TIME_WAIT 连接数超过 10000 就要小心了。调一下 tcp_fin_timeout 能缓解:
```bash
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
```
## 监控配置
| 指标 | 告警阈值 | 处理建议 |
|------|----------|----------|
| TCP 连接成功率 | < 99% | 检查网络链路 |
| DNS 解析延迟 | > 500ms | 换就近 DNS |
| SSL 握手时间 | > 2000ms | 检查证书链 |
| upstream 响应时间 | > 3000ms | 扩容或优化后端 |
Prometheus 告警规则示例:
```yaml
groups:
- name: career-ops-alerts
rules:
- alert: CareerOpsHighTimeoutRate
expr: rate(career_ops_timeout_total[5m]) > 0.05
for: 2m
labels:
severity: critical
```
## 小结
排查连接超时的思路就是逐层定位、排除验证。从网络层到传输层再到应用层,先底层后上层,MTTR 能缩短不少。
实操建议建立标准化 checklist,tcpdump 抓包配合防火墙日志联动分析,90% 以上的场景都能覆盖。career-ops 本身的话,多留意 token 有效期和服务注册状态,这两个是高频踩坑点。
延伸阅读:如果遇到 HTTPS 证书问题导致的连接中断,用这个命令查 TLS 握手:`openssl s_client -connect career-ops.internal:443 -state`。
你们那边有遇到什么奇葩的超时问题吗?评论区来聊聊。 |
|