公司后台从单体应用拆成十几个微服务后,突然发现用户下单老是卡在支付回调环节——查日志没报错,但接口就是超时。这不是代码问题,是网络保障没跟上。
别只盯着服务,先管好网络通道
微服务之间靠 HTTP 或 gRPC 通信,一次用户请求可能横跨 5~8 个服务节点。中间只要一个网络抖动、DNS 解析慢、连接池耗尽,整条链路就卡住。比如某次内网 DNS 服务器响应延迟从 5ms 涨到 300ms,订单服务调用库存服务的平均耗时直接翻了 4 倍。
三招快速加固网络层
1. 限制连接数 + 合理超时
Spring Cloud 默认的 Apache HttpClient 连接池不设上限,高并发下容易打满系统句柄。建议在 application.yml 中显式配置:
spring:
cloud:
loadbalancer:
configurations: default
config:
connect-timeout: 2000
read-timeout: 5000
ribbon:
MaxConnectionsPerHost: 50
MaxTotalConnections: 2002. 本地 DNS 缓存别依赖系统默认
Java 应用默认缓存 DNS 30 秒(Linux 系统级缓存更久),一旦服务实例 IP 变更(比如 K8s Pod 重建),就会出现「连得上但连错」的问题。在启动脚本里加这行:
-Dnetworkaddress.cache.ttl=60 -Dnetworkaddress.cache.negative.ttl=103. 内网走直连,别绕注册中心兜圈子
同机房服务调用,硬要通过 Eureka/Nacos 查地址再发请求,多了一跳网络+一次序列化反序列化。用 Kubernetes 的 Headless Service 配合 DNS SRV 记录,服务名直接解析为 Pod IP,curl http://user-service:8080/api/profile 就能直连,延迟压到 3ms 内。
排查时先看这几个地方
• netstat -an | grep :8080 | wc -l —— 看端口连接数是否接近 ulimit 上限
• cat /proc/sys/net/ipv4/ip_local_port_range —— 检查可用临时端口范围,小厂常卡在默认的 32768–65535
• ss -ti —— 查看 TCP 重传率(retrans)和 rtt,超过 2% 就该怀疑物理链路或交换机丢包
某次凌晨告警,订单服务大量 Connection refused,登录机器一看:ss -s 显示已用端口 65490,只剩 45 个可用——原来是日志里有个定时任务每秒新建 HTTP 客户端却没 close,跑了一周把端口池吃光了。
网络保障不是加个负载均衡器就完事,它藏在每次 DNS 查询、每个 socket 创建、每毫秒的 RTT 波动里。服务拆得越细,越得把网络当「第一等公民」来养。