网络排障¶
学习目标¶
学完本章后,学习者应该能够:
- 掌握 ping、traceroute、curl、nc、dig、ss、tcpdump 的基本用途。
- 能按 DNS、TCP、TLS、HTTP、应用处理分层排查超时。
- 能读懂常见网络错误信息。
- 能写出生产网络问题的排查记录。
排障思路¶
不要一上来猜。先把问题拆成阶段:
- 域名是否能解析?
- 目标 IP 是否可达?
- TCP 端口是否能连接?
- TLS 握手是否成功?
- HTTP 状态码是什么?
- 请求是否到达应用?
- 应用是否卡在下游依赖?
每一步都要用工具或日志验证。
常用工具¶
| 工具 | 用途 |
|---|---|
| ping | 粗略测试连通性和延迟 |
| traceroute / tracert | 查看路由路径 |
| curl | 测试 HTTP / HTTPS |
| telnet / nc | 测试 TCP 端口连通性 |
| dig / nslookup | 测试 DNS |
| ss / netstat | 查看连接和监听状态 |
| tcpdump | 抓包分析 |
常见错误¶
| 错误 | 可能方向 |
|---|---|
| no such host | DNS 解析失败 |
| connection refused | 端口未监听或被拒绝 |
| connection timed out | 网络不通、防火墙、服务无响应 |
| connection reset by peer | 对端重置连接 |
| TLS handshake timeout | TLS 握手慢或失败 |
| context deadline exceeded | Go context 超时 |
| i/o timeout | 网络 IO 超时 |
Go 后端实际应用例子¶
例子一:给错误打上阶段标签¶
func FetchJSON(ctx context.Context, client *http.Client, url string) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return fmt.Errorf("build request: %w", err)
}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("do request: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode >= 500 {
return fmt.Errorf("upstream status: %d", resp.StatusCode)
}
return nil
}
错误信息要让排障者知道失败阶段,而不是只返回“请求失败”。
例子二:记录关键网络字段¶
调用外部服务时建议记录:
- target host。
- method。
- status code。
- latency。
- error type。
- retry count。
- request id。
这些字段能帮助你在事故时快速区分是网络、代理、下游服务还是自身问题。
跨平台命令¶
常见误区¶
- 误区一:只看应用日志。
请求可能根本没到应用。代理日志、负载均衡日志、DNS、TCP 和 TLS 都要看。
- 误区二:只看平均延迟。
网络问题常表现为长尾延迟和偶发失败。P95、P99、错误率更关键。
- 误区三:排障命令能替代监控。
命令适合现场验证,生产系统仍需要持续指标、日志和链路追踪。
线上问题案例¶
某 API 偶发 context deadline exceeded。一开始怀疑 Go 服务慢,但链路追踪显示请求卡在调用 Redis。继续查看 Redis 连接池指标,发现连接池耗尽,请求排队等待连接。
修复方式是调整连接池、减少慢命令、增加超时指标,并在日志中区分“连接池等待耗时”和“Redis 执行耗时”。
实战任务¶
给出“访问 https://api.example.com 超时”的排查步骤:
- 检查 DNS。
- 检查 TCP 端口。
- 检查 TLS。
- 检查 HTTP 状态。
- 检查应用日志和代理日志。
- 记录结论和下一步。
参考答案
先用 dig 或 nslookup 确认域名能解析,并记录解析 IP。再用 nc、Test-NetConnection 或 curl -v 检查 443 端口是否可连。curl -v 可以观察 TLS 握手和 HTTP 状态码。
如果请求没有到应用日志,重点看负载均衡、网关、防火墙、安全组、证书和路由。如果应用收到请求但处理慢,继续看应用耗时分段、下游依赖、数据库、缓存和连接池。排障记录要写明每一步证据,而不是只写“网络问题”。
面试题¶
1. connection refused 和 connection timed out 有什么区别?¶
参考答案
connection refused 通常表示目标主机可达,但目标端口没有服务监听,或主动拒绝连接。connection timed out 通常表示连接请求没有得到响应,可能是网络不通、防火墙丢包、安全组拦截或服务严重无响应。
两者排查方向不同:refused 先看监听端口和服务状态;timeout 先看路由、防火墙、安全组和网络连通性。
2. curl -v 能帮助观察什么?¶
参考答案
curl -v 可以显示 DNS 结果、连接目标、TLS 握手、请求 Header、响应 Header 和状态码等信息。
它适合快速判断问题发生在 DNS、TCP、TLS、HTTP 还是应用响应阶段。
3. tcpdump 适合什么时候使用?¶
参考答案
tcpdump 适合在日志和普通命令无法解释问题时抓包验证,例如确认是否发出了 SYN、是否收到 SYN+ACK、是否有重传、RST、TLS 握手失败或包被发送到错误地址。
抓包成本较高,生产环境使用时要控制过滤条件、时间和数据量,避免采集敏感信息。