预期部署方案:两个eureka+三个相关应用
注册时应用出现:Request execution failed with message: Cannot invoke “Object.getClass()” because “authScheme” is null,一开始认为未正确传递eureka配置的账户+密码,例:defaultZone: http://username:password@dev.bab.cn:8761/eureka/,检查后发现一切正常,后续排查后得出结论 hostname不能是127.0.0.1,必须为容器内ip(本次直接配置的是外部转发域名),调整为hostname: ${POD_IP},当然也可能是受多个因素影响,如集群网络不通、端口或eureka启动端口配置不争气等:
spring:
security:
basic:
enabled: true
user:
name: eureka
password: abc123456
eureka:
datacenter: user-server
environment: prod
instance:
hostname: ${POD_IP} # 容器部署必须填写docker容器的ip
instance-id: ${random.uuid}
client:
# For stand-alone deployment, the following is false 单机部署的话以下为false
register-with-eureka: ${IS_CLUSTERED:false}
fetch-registry: ${IS_CLUSTERED:false}
service-url:
defaultZone: http://eureka:abc123456@bab.com/eureka/
网上其他说法总结:
- 降级jdk到8(本次是openjdk17)
- 升级spring core(本次spring boot3.0,core已经达到6.0)
- 添加禁用csrf:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.csrf().disable().httpBasic(); return http.build(); }
- 禁用csrf方案2(来自stack overflow):
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authConfig -> authConfig.anyRequest().authenticated()) .httpBasic(httpBasic -> { }) .logout(logout -> { logout.logoutUrl("/logout"); logout.addLogoutHandler((request, response, authentication) -> authentication.setAuthenticated(false)); }); return http.build(); }
- 禁用csrf方案3:
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests() .anyRequest().authenticated() // 任何请求都不需要认证:.anyRequest().permitAll() .and() .httpBasic(); return http.build(); }
以上办法都没有成功,而且还导致额外出现Root name ‘timestamp’ does not match expected错误。
遇到的其他问题:eureka存在两个实例时相关服务注册完成后自动断开,排查后因为两个eureka没有将register-with-eureka和etch-registry同时设置为true,且defaultZone的地址不是相互注册状态eureka1填写eureka2的ip、eureka2填写eureka1的ip,可减少为1台或重新配置defaultZone的ip