目录
背景:
问题及方案
1 Kubernetes-pom文件中的依赖包名称不同
2 项目引入 OpenFeign 或者 RestTemplate 启动假死
解决方案有以下三种:
1、使用异步方法并且延迟注入 OpenFeignClient (推荐)
2、使用 webclient 代替 Feign
3、关闭基于权重的负载平衡
3 升级之后,feign调用报错
4 熔断机制的核心类库发生变化
5 Not running inside kubernetes. Skipping 'kubernetes' profile activation.
旧版本:
Spring boot:2.1.8
Spring cloud:Greenwich.SR3
JDK:1.8
新版本:
Spring boot:2.6.8
Spring cloud:2021.0.3
JDK:1.8
这个问题有点坑,当时我问了一下度娘,也没有找到答案,最后上官网查看了一下,才发现问题,所以,以后遇到问题,应该先去官方文档看看,可以解决百分之九十九的问题
文档地址:Spring Cloud Kubernetes | 中文文档
低版本的名称是:
org.springframework.cloud
spring-cloud-starter-kubernetes-config
高版本的名称是:
org.springframework.cloud
spring-cloud-starter-kubernetes-fabric8-config
项目升级之后,启动出现以下情况
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.8)
[2023-02-09 09:46:23.470] [main] [INFO] [org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration] - Located property source: [BootstrapPropertySource {name='bootstrapProperties-configmap.demo-configmap.test'}]
[2023-02-09 09:46:23.508] [main] [INFO] [org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration] - Located property source: [BootstrapPropertySource {name='bootstrapProperties-secrets.demo-secret.test'}]
[2023-02-09 09:46:23.569] [main] [WARN] [org.springframework.cloud.kubernetes.commons.profile.AbstractKubernetesProfileEnvironmentPostProcessor] - Not running inside kubernetes. Skipping 'kubernetes' profile activation.
[2023-02-09 09:46:23.573] [main] [INFO] [cn.test.gateway.Application] - No active profile set, falling back to 1 default profile: "default"
[2023-02-09 09:46:24.365] [main] [INFO] [org.springframework.cloud.context.scope.GenericScope] - BeanFactory id=240c07a9-2d7f-39d9-8549-b9fae3417bf0
[2023-02-09 09:46:24.443] [main] [INFO] [org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker] - Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2023-02-09 09:46:24.444] [main] [INFO] [org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker] - Bean 'org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig' of type [org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration$ReactorDeferringLoadBalancerFilterConfig] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2023-02-09 09:46:24.445] [main] [INFO] [org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker] - Bean 'reactorDeferringLoadBalancerExchangeFilterFunction' of type [org.springframework.cloud.client.loadbalancer.reactive.DeferringLoadBalancerExchangeFilterFunction] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[2023-02-09 09:46:25.623] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [After]
[2023-02-09 09:46:25.623] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Before]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Between]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Cookie]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Header]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Host]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Method]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Path]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Query]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [ReadBody]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [RemoteAddr]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [XForwardedRemoteAddr]
[2023-02-09 09:46:25.624] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [Weight]
[2023-02-09 09:46:25.625] [main] [INFO] [org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator] - Loaded RoutePredicateFactory [CloudFoundryRouteService]
[2023-02-09 09:46:28.548] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'cn-demo-v5-wsserver'.
[2023-02-09 09:46:28.549] [boundedElastic-9] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'istiod'.
[2023-02-09 09:46:28.567] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.566] [boundedElastic-9] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.569] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.573] [boundedElastic-9] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.574] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
[2023-02-09 09:46:28.574] [boundedElastic-9] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
[2023-02-09 09:46:28.577] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'cn-test-v5-wsserver'.
[2023-02-09 09:46:28.577] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.577] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.577] [boundedElastic-12] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
[2023-02-09 09:46:28.789] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'kube-dns'.
[2023-02-09 09:46:28.789] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'kube-dns'.
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.790] [boundedElastic-13] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
[2023-02-09 09:46:28.828] [boundedElastic-4] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Could not find a port named 'https' or 'http' for service 'selenium-hub'.
[2023-02-09 09:46:28.828] [boundedElastic-4] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Make sure that either the primary-port-name label has been added to the service, or that spring.cloud.kubernetes.discovery.primary-port-name has been configured.
[2023-02-09 09:46:28.828] [boundedElastic-4] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - Alternatively name the primary port 'https' or 'http'
[2023-02-09 09:46:28.828] [boundedElastic-4] [WARN] [org.springframework.cloud.kubernetes.fabric8.discovery.KubernetesDiscoveryClient] - An incorrect configuration may result in non-deterministic behaviour.
不要着急,我自有解决方案,不过先分析一下原因:
是因为启动的时候有死锁导致的。 初始化Bean的时候,主线程执行到DefaultSingletonBeanRegistry.getSingleton方法,会持有一个锁。 然后项目里用了openfeign,在openfeign初始化的时候,会发布一个RefreshRoutesEvent事件,刚好被WeightCalculatorWebFilter捕获到了,执行了routeLocator.ifAvailable(locator -> locator.getRoutes().blockLast());这句代码,blockLast的时候,主线程就挂起了,锁没释放。 然后有其他线程执行到DefaultSingletonBeanRegistry.getSingleton方法的时候(比如上面的locator.getRoutes,实际是异步执行的,线程会调用到DefaultSingletonBeanRegistry.getSingleton方法), 就死锁启不起来了
注意点如下:
核心代码实例:
注意点如下
注入 OpenFeignClient 必须使用 @Lazy
FeignClent 必须要异步调用,不能同步调用,不然会报不能在xxx线程执行的错
使用 @EnableFeignClients ,开启 OpenFeign 功能
使用 @EnableAsync 开启异步执行功能,不然加了 @Async 注解也没用。或者自定义 ExecutorService 进行异步处理。
#
示例代码如下:
//第一步 注入webclident
@Bean
@LoadBalanced // 如果不添加,无法通过服务名进行调用,只能通过ip调用
public WebClient.Builder webBuilder(){
return WebClient.builder();
}
//第二步 在gateway当中注入
@Autowired
WebClient.Builder webBuilder;
//第三步 具体调用方式 这里的“lb”也可以换成http
Mono
spring.cloud.gateway.predicate.weight.enabled设置为true时,将为网关中定义的路由,启用基于权重的负载平衡。设置为false时,将禁用基于权重的负载平衡,并且流量将平均分配给服务的所有实例。
报错信息如下
[2023-02-10 17:50:10.481] [reactor-http-nio-3] [INFO] [cn.test.gateway.filters.Filter] - token:4ac15ea7193ba0f1922883dfabc4d48e
[2023-02-10 17:50:12.003] [reactor-http-nio-3] [ERROR] [org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler] - [8f4cbb3e-1] 500 Server Error for HTTP GET "/v1_admin/goods/battery/admin/info"
feign.RetryableException: Unexpected end of file from server executing GET http://test-admin:8081/test/get?sign=9923dfc364eef935b02b3d55b1324bae&sign_type=MD5×tamp=1676022610
at feign.FeignException.errorExecuting(FeignException.java:268) ~[feign-core-11.8.jar:?]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
*__checkpoint ⇢ HTTP GET "/v1_admin/goods/battery/admin/info" [ExceptionHandlingWebHandler]
Original Stack Trace:
at feign.FeignException.errorExecuting(FeignException.java:268) ~[feign-core-11.8.jar:?]
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:129) ~[feign-core-11.8.jar:?]
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89) ~[feign-core-11.8.jar:?]
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100) ~[feign-core-11.8.jar:?]
at com.sun.proxy.$Proxy137.getManagedAuthAndAppByToken(Unknown Source) ~[?:?]
原因:Spring cloud高版本启动时无法自动加载消息解释器
解决方法:
@Configuration
public class HttpMessageConvertersConfig {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}
在spring-cloud-openfeign2.2.10版本时已经有CircuitBreakers替换掉hystrix的趋势,在3.1.3已经完全被替换掉
文档参考:Spring Cloud OpenFeign
源码:
void addKubernetesProfile(ConfigurableEnvironment environment) {
Pod current = utils.currentPod().get();
if (current != null) {
if (!hasKubernetesProfile(environment)) {
environment.addActiveProfile(KUBERNETES_PROFILE);
}
}
if (utils.isInsideKubernetes()) {
if (hasKubernetesProfile(environment)) {
LOGGER.debug("'kubernetes' already in list of active profiles");
} else {
LOGGER.debug("Adding 'kubernetes' to list of active profiles");
environment.addActiveProfile(KUBERNETES_PROFILE);
}
} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.warn("Not running inside kubernetes. Skipping 'kuberntes' profile activation.");
}
}
}
设置环境变量,项目启动的时候,会从环境变量中获取Kubernetes相关配置
希望以上信息对大家有所帮助!!!