公司把单体应用拆成十几个微服务后,突然发现订单超时多、支付回调老失败——查日志没报错,看服务器资源也宽松,最后抓包一瞅:90%的跨服务请求卡在300ms以上。问题不在代码,而在路由没跟上架构变化。
别只盯着服务发现,路由才是微服务的毛细血管
很多团队以为上了Consul或Nacos就万事大吉,其实服务注册只是第一步。真实场景里,A服务调B服务,可能走的是默认网关路径,中间绕了两跳防火墙+一个负载均衡器;而C服务调D服务却直连Pod IP——这种不一致的路由路径,会让链路延迟忽高忽低,熔断策略频频误触发。
三个必须检查的路由层
1. 服务网格入口路由:Istio的VirtualService配置里,是否为关键链路(如用户登录→鉴权→用户中心)设置了专用的timeout和重试策略?别让所有流量共用一个5s超时。
2. 容器网络层路由:K8s Service类型选NodePort还是ClusterIP?如果用了Calico,有没有在BGP模式下把核心微服务所在节点打上特定路由标签,避免跨机房转发?
3. 主机层路由表:有些老旧物理机混在集群里,ifconfig一看,default route指向的是千兆交换机,而微服务间通信实际走的是万兆RDMA网卡——得手动加一条到10.200.0.0/16网段的静态路由,直指rdma0接口。
一个小而管用的调优动作
在API网关(比如Kong)里,给每个微服务上游配置独立的upstream,并开启keepalive:
upstream payment-svc {
keepalive 32;
keepalive_timeout 60s;
keepalive_requests 1000;
}实测某电商项目,把payment-svc的keepalive从默认关闭调到32后,平均RT下降47ms,连接复用率从12%升到89%。
别忽视DNS这一环
微服务间用service-name调用,背后全靠DNS解析。如果CoreDNS部署在单点Master上,又没配好forward和cache_ttl,一次解析可能耗时200ms。建议在每个Node上跑dnsmasq作为本地缓存,/etc/resolv.conf头两行写死127.0.0.1和CoreDNS ClusterIP,避免轮询慢节点。
路由不是上线前配一次就完事的事。每周抽15分钟,用mtr命令扫一遍核心服务间的三层路径:mtr -r -c 10 payment.svc.cluster.local,看丢包点和跳数突变,比等告警更早发现问题。