spring cloud kubernetes在pod模式下服务调用源码解析_水中加点糖-CSDN博客

之所以只看pod模式下的服务调用链路,是因为在service模式下不会走缓存,效率低,并且负载均衡模式不能由spring cloud框架所控制,不太灵活


需要关注的几个类:

DiscoveryClient

org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient

org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient#choose(java.lang.String, org.springframework.cloud.client.loadbalancer.Request)

      publicServiceInstancechoose(StringserviceId,Requestrequest){ReactiveLoadBalancerloadBalancer=this.loadBalancerClientFactory.getInstance(serviceId);if(loadBalancer==null){returnnull;}else{ResponseloadBalancerResponse=(Response)Mono.from(loadBalancer.choose(request)).block();returnloadBalancerResponse==null?null:(ServiceInstance)loadBalancerResponse.getServer();}}

org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory#getInstance

      publicReactiveLoadBalancergetInstance(StringserviceId){return(ReactiveLoadBalancer)this.getInstance(serviceId,ReactorServiceInstanceLoadBalancer.class);}

feign调用
implements ReactorServiceInstanceLoadBalancer

feign调用时用的org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient中的execute方法调用的。
其中获取服务列表的代码为:ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);
也就是org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient#choose(java.lang.String, org.springframework.cloud.client.loadbalancer.Request)这个方法,其中用的此方法:

      ReactiveLoadBalancer loadBalancer = this.loadBalancerClientFactory.getInstance(serviceId);

其中的loadBalancerClientFactory字段是在BlockingLoadBalancerClient初始化时设置的。需要看一下loadBalancerClientFactory传入的地方。
也就是org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient类初始化时LoadBalancerClient注入进去的是哪个类。
这个类的属于commons的包里,看一下其中loadbalancer中关于初始化的地方。

代码在此处:
org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration#blockingLoadBalancerClient

      @Bean
	@ConditionalOnBean(LoadBalancerClientFactory.class)
	@ConditionalOnMissingBean
	public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) {
		return new BlockingLoadBalancerClient(loadBalancerClientFactory);
	}

这里注入了一个LoadBalancerClientFactory,这经的注入代码在此处:org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration#loadBalancerClientFactory

      @ConditionalOnMissingBean
	@Bean
	public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) {
		LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties);
		clientFactory.setConfigurations(this.configurations.getIfAvailable(Collections::emptyList));
		return clientFactory;
	}

这个factory的代码中的getInstance方法:

      @Override
	public ReactiveLoadBalancer getInstance(String serviceId) {
		return getInstance(serviceId, ReactorServiceInstanceLoadBalancer.class);
	}

获取的是ReactorServiceInstanceLoadBalancer.class

则需要找到ReactorServiceInstanceLoadBalancer的实现类:
org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration#reactorServiceInstanceLoadBalancer

      @Bean
	@ConditionalOnMissingBean
	public ReactorLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment,
			LoadBalancerClientFactory loadBalancerClientFactory) {
		String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
		return new RoundRobinLoadBalancer(
				loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
	}

其中用懒加载获取的ServiceInstanceListSupplier的bean。

那么如果是service模式下,其中的ServiceInstanceListSupplier的实现类为:org.springframework.cloud.kubernetes.client.loadbalancer.KubernetesClientServicesListSupplier,其初始化代码为:

      @Bean
	@ConditionalOnProperty(name = "spring.cloud.kubernetes.loadbalancer.mode", havingValue = "SERVICE")
	KubernetesServicesListSupplier kubernetesServicesListSupplier(Environment environment, CoreV1Api coreV1Api,
			KubernetesClientServiceInstanceMapper mapper, KubernetesDiscoveryProperties discoveryProperties,
			KubernetesNamespaceProvider kubernetesNamespaceProvider) {
		return new KubernetesClientServicesListSupplier(environment, mapper, discoveryProperties, coreV1Api,
				kubernetesNamespaceProvider);
	}

如果是pod模式,则使用的默认的初始化代码:org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration.ReactiveSupportConfiguration#discoveryClientServiceInstanceListSupplier
其代码为:

      @Bean
		@ConditionalOnBean(ReactiveDiscoveryClient.class)
		@ConditionalOnMissingBean
		@Conditional(DefaultConfigurationCondition.class)
		public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
				ConfigurableApplicationContext context) {
			return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().build(context);
		}

其中withDiscoveryClient方法:

      /**
	 * Sets a {@link ReactiveDiscoveryClient}-based
	 * {@link DiscoveryClientServiceInstanceListSupplier} as a base
	 * {@link ServiceInstanceListSupplier} in the hierarchy.
	 * @return the {@link ServiceInstanceListSupplierBuilder} object
	 */
	public ServiceInstanceListSupplierBuilder withDiscoveryClient() {
		if (baseCreator != null && LOG.isWarnEnabled()) {
			LOG.warn("Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator.");
		}
		this.baseCreator = context -> {
			ReactiveDiscoveryClient discoveryClient = context.getBean(ReactiveDiscoveryClient.class);

			return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment());
		};
		return this;
	}

其中ReactiveDiscoveryClient的bean为:

      @Bean
	@ConditionalOnMissingBean
	public KubernetesInformerReactiveDiscoveryClient kubernetesReactiveDiscoveryClient(
			KubernetesNamespaceProvider kubernetesNamespaceProvider, SharedInformerFactory sharedInformerFactory,
			Lister serviceLister, Lister endpointsLister,
			SharedInformer serviceInformer, SharedInformer endpointsInformer,
			KubernetesDiscoveryProperties properties) {
		return new KubernetesInformerReactiveDiscoveryClient(kubernetesNamespaceProvider, sharedInformerFactory,
				serviceLister, endpointsLister, serviceInformer, endpointsInformer, properties);
	}

public class KubernetesInformerReactiveDiscoveryClient implements ReactiveDiscoveryClient

所以由此可以看出,k8s中pod模式下用的是KubernetesInformerReactiveDiscoveryClient。
所以如果想要到达k8s模式下的个性化定制,可以参考官方文档https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#hints-based-loadbalancing,
参考代码:
org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplierBuilder#withHints

你可能感兴趣的:(spring cloud kubernetes在pod模式下服务调用源码解析_水中加点糖-CSDN博客)