跨中心服务发现需配置eureka.client.serviceurl.defaultzone为逗号分隔的多中心eureka地址,如http://eureka-a:8761/eureka/,http://eureka-b:8761/eureka/;各中心hostname须设为跨中心可解析域名;客户端按序重试且不缓存失败节点,需调低连接超时;关闭ribbon后应启用spring cloud loadbalancer并自定义serviceinstancelistsupplier与机房标签路由;数据库跨中心读写分离须依赖网关或shardingsphere等中间件,而非@transactional(readonly=true);health检查需扩展下游中心探活并控制超时;readinessprobe initialdelayseconds至少设为15秒;故障判定阈值需通过真实故障注入反复验证。

跨中心服务发现失效时,eureka.client.serviceUrl.defaultZone 怎么配才不绕路
多活中心下,Eureka 客户端若只写单中心地址,一中心挂掉就直接注册失败,不是“自动切”,而是“根本没机会切”。关键在让客户端能同时感知多个中心的 Eureka Server,但又不能无脑堆地址。
- 必须用逗号分隔多个
defaultZoneURL,例如:http://eureka-a:8761/eureka/,http://eureka-b:8761/eureka/;单写一个地址 + 配置eureka.client.shouldUseDns无效 - 各中心 Eureka Server 的
eureka.instance.hostname必须设为跨中心可解析的域名(如eureka-a.prod.dc1.example.com),不能用localhost或本地内网 IP - 客户端启动时会按顺序尝试连接,第一个连不上就试下一个——但不会缓存“哪个挂了”,每次心跳都重试全部地址,所以 DNS 解析延迟和连接超时(
eureka.client.eurekaServerConnectTimeoutSeconds)得调低,否则卡住 30 秒才切
spring.cloud.loadbalancer.ribbon.enabled=false 关闭 Ribbon 后,OpenFeign 怎么走跨中心路由
Ribbon 默认不支持按机房标签做优先级路由,硬切容易跨中心打请求。关掉它不是为了不用负载均衡,而是换更可控的方案。
- 启用
spring.cloud.loadbalancer.enabled=true(Spring Cloud 2020+ 默认),配合自定义ServiceInstanceListSupplier - 在
getInstanceId()返回值里嵌入机房标识(如user-service#dc1),再通过DefaultLoadBalancerCache缓存带标签的实例列表 - Feign 调用前,用
RequestContextHolder拿到上游传来的X-RegionHeader,动态过滤出同机房实例;没匹配到再 fallback 到其他中心——这个逻辑必须自己写,框架不代劳
数据库主从跨中心同步延迟导致读到脏数据,@Transactional(readOnly = true) 不起作用怎么办
注解只影响 Spring 的事务传播行为,不控制物理连接目标。跨中心读写分离网关(如 MyCat、ShardingSphere)或应用层路由才是关键。
- 别依赖 ORM 的 readOnly 提示,它对底层 JDBC 连接没强制约束;真正生效的是数据源路由策略
- 用
ShardingSphere-JDBC时,配置readwrite-splitting规则,并设置load-balancer-name: RANDOM或自定义SQLHint强制走写库 - 强一致性读场景(如提交后立刻查),加
/*+ FORCE_MASTER */注释(MySQL)或显式用masterDataSourceBean,而不是靠注解猜
故障切换时 actuator/health 状态滞后,K8s readinessProbe 误杀健康实例
默认 HealthIndicator 检查的是本地组件(DB 连接、Redis),不反映跨中心依赖是否真实可用。等它报 down,流量早切过去了,或者切早了把好实例干掉了。
- 重写
CompositeHealthIndicator,把核心下游中心的/actuator/health也作为子检查项,超时设为 2 秒以内,失败直接标DOWN - K8s 中
readinessProbe的initialDelaySeconds至少设为 15 秒——Eureka 注册、配置拉取、健康检查链路初始化全跑完再开始探活 - 避免在
health接口里调用非幂等操作(如发 MQ、改 DB),它会被 kubelet 高频轮询,容易引发副作用
跨中心切换真正的复杂点不在代码怎么写,而在于“什么算故障”的判定边界——网络抖动、DB 主从延迟、Eureka 心跳丢失,这三类信号的响应阈值稍有偏差,就会在可用性与一致性之间反复横跳。得拿真实故障注入反复调,不能只看文档参数。










