迁移的文档:
https://www.alibabacloud.com/help/zh/edas/developer-reference/smoothly-migrate-a-spring-cloud-cluster-that-contains-multiple-applications-to-edas
其中遇到的问题
未配置排除配置项时(exclude = {RibbonEurekaAutoConfiguration.
class
})
,ribbonServerList不是我需要的MigrationRibbonConfiguration.ribbonServerList 的bean。造成双注册中心失效。未配置成功。
使用此配置会造成依然是单注册中心eureka。无法达到要求
如下图:
回溯这个问题初始化ribbonServerList的bean时,有一个注解:
@ConditionalOnMissingBean 它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果而注册相同类型的bean,就不会成功,它会保证你的bean只有一个,即你的实例只有一个。
换句话是指: 这个bean谁先来用谁。这个方法均有注解:@ConditionalOnMissingBean
org.springframework.cloud.netflix.ribbon.eureka.EurekaRibbonClientConfiguration#ribbonServerList
com.alibaba.edas.ribbon.MigrationRibbonConfiguration#ribbonServerList
org.springframework.cloud.alibaba.nacos.ribbon.NacosRibbonClientConfiguration#ribbonServerList
那就看创建bean的时候:
发现bean的定义信息就不对了,不应该是eurekaRibbonClientConfiguration。应该是MigrationRibbonConfiguration才对。
那就找mbd的生成位置
看:getBeanDefinition 方法
this.beanDefinitionMap 出现了问题,那就找这个map.put的位置:注册bean的定义信息的方法:
bean的定义信息已经出现了问题
因为eurekaRibbonClientConfiguration、migrationRibbonConfiguration、nacosRibbonClientConfiguration 是都有ribbonServerList的方法的,还有一个@ConditionalOnMissingBean的注解。需要将migrationRibbonConfiguration调到前面。
由于eurekaRibbonClientConfiguration进行优先加载,则ribbonServerList就使用eureka的了:
那么
回来看入参:
,发现configCandidates属性是add添加的,来自于: registry.getBeanDefinitionNames();
,确认registry是DefaultListableBeanFactory类,找对应的方法
,找到这list.add的地方:
,然后能找那个地方在循环调用:看堆栈信息:
,然后发现eureka跑到项目的主类的前面去了。然后再找configurations赋值的地方:
只有一个:
确定是list转Map顺序变了:
解决办法:
1、改项目名称(离谱法):
之前叫GatewayApplicant,现在叫DemoApplication
顺序正确,看ribbonServerList:
2、排除RibbonEurekaAutoConfiguration
自动配置
ribbonServerList:
好,问题解决