Browse Source

spring cloud 2021.x 源码阅读, OpenFeign + LoadBalancer + Nacos Discovery

hekai-study-v2021.x
Kai 11 months ago
parent
commit
ecaf9f2958
  1. 24
      pom.xml
  2. 5
      spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java
  3. 25
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java
  4. 6
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java
  5. 4
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java
  6. 39
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java
  7. 22
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java
  8. 23
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java
  9. 9
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java
  10. 5
      spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java

24
pom.xml

@ -62,10 +62,10 @@
<groupId>io.spring.javaformat</groupId> <groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId> <artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin> </plugin>
<plugin> <!-- <plugin>-->
<groupId>org.apache.maven.plugins</groupId> <!-- <groupId>org.apache.maven.plugins</groupId>-->
<artifactId>maven-checkstyle-plugin</artifactId> <!-- <artifactId>maven-checkstyle-plugin</artifactId>-->
</plugin> <!-- </plugin>-->
<plugin> <plugin>
<groupId>org.basepom.maven</groupId> <groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId> <artifactId>duplicate-finder-maven-plugin</artifactId>
@ -73,14 +73,14 @@
</plugins> </plugins>
</build> </build>
<reporting> <!-- <reporting>-->
<plugins> <!-- <plugins>-->
<plugin> <!-- <plugin>-->
<groupId>org.apache.maven.plugins</groupId> <!-- <groupId>org.apache.maven.plugins</groupId>-->
<artifactId>maven-checkstyle-plugin</artifactId> <!-- <artifactId>maven-checkstyle-plugin</artifactId>-->
</plugin> <!-- </plugin>-->
</plugins> <!-- </plugins>-->
</reporting> <!-- </reporting>-->
<profiles> <profiles>
<profile> <profile>

5
spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.context.named; package org.springframework.cloud.context.named;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.util.Iterator; import java.util.Iterator;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -36,10 +36,13 @@ class ClientFactoryObjectProvider<T> implements ObjectProvider<T> {
private final NamedContextFactory<?> clientFactory; private final NamedContextFactory<?> clientFactory;
// 服务的名称
private final String name; private final String name;
// 固定为ServiceInstanceListSupplier
private final Class<T> type; private final Class<T> type;
// 隔离provider,provider只返回clientFactory中指定name,type的数据
private ObjectProvider<T> provider; private ObjectProvider<T> provider;
ClientFactoryObjectProvider(NamedContextFactory<?> clientFactory, String name, Class<T> type) { ClientFactoryObjectProvider(NamedContextFactory<?> clientFactory, String name, Class<T> type) {

25
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.annotation; package org.springframework.cloud.loadbalancer.annotation;
// comment-by-kai 源码阅读 spring cloud 2021.x
import reactor.util.retry.RetrySpec; import reactor.util.retry.RetrySpec;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
@ -63,20 +63,28 @@ public class LoadBalancerClientConfiguration {
private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465; private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465;
// 首先,在前文可以看到在 LoadBalancerAutoConfiguration 配置中,配置了 LoadBalancerClientFactory ,其实例 bean 存在于父容器中,
// 而当前配置类 LoadBalancerClientConfiguration 通过构造函数会当成默认配置类注册到 NamedContextFactory 的子容器中,每个子容器都拥有。
// 只有明白了这一点,才能够理解容器的隔离。
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean // ConditionalOnMissingBean 说明可以自己实现这个bean,来覆盖默认的配置。
public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) { LoadBalancerClientFactory loadBalancerClientFactory) {
// name表示服务名称,比如stock-service
// LoadBalancerClientFactory bean的配置:参考代码 LoadBalancerAutoConfiguration
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RoundRobinLoadBalancer( return new RoundRobinLoadBalancer(
loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
} }
// ============================= Reactive Retry ============================= //
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnReactiveDiscoveryEnabled @ConditionalOnReactiveDiscoveryEnabled
@Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER) @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER)
public static class ReactiveSupportConfiguration { public static class ReactiveSupportConfiguration {
// ReactiveDiscoveryClient + DefaultConfigurationCondition
@Bean @Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class) @ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ -86,6 +94,7 @@ public class LoadBalancerClientConfiguration {
return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().build(context); return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().build(context);
} }
// ReactiveDiscoveryClient + ZonePreferenceConfigurationCondition
@Bean @Bean
@ConditionalOnBean(ReactiveDiscoveryClient.class) @ConditionalOnBean(ReactiveDiscoveryClient.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ -134,11 +143,17 @@ public class LoadBalancerClientConfiguration {
} }
// ============================= Blocking Retry ============================= //
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnBlockingDiscoveryEnabled @ConditionalOnBlockingDiscoveryEnabled
@Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER + 1) @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER + 1)
public static class BlockingSupportConfiguration { public static class BlockingSupportConfiguration {
// 真正获取 ServiceInstance 列表的 由 ServiceInstanceListSupplier 提供,
// 这里可以看到可以由 DiscoveryClient 提供。这样就已经跟注册中心客户端联系上了。
// DiscoveryClient + DefaultConfigurationCondition
@Bean @Bean
@ConditionalOnBean(DiscoveryClient.class) @ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ -148,6 +163,7 @@ public class LoadBalancerClientConfiguration {
return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching().build(context); return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching().build(context);
} }
// DiscoveryClient + ZonePreferenceConfigurationCondition
@Bean @Bean
@ConditionalOnBean(DiscoveryClient.class) @ConditionalOnBean(DiscoveryClient.class)
@ConditionalOnMissingBean @ConditionalOnMissingBean
@ -190,6 +206,8 @@ public class LoadBalancerClientConfiguration {
} }
// ============================= Blocking Retry ============================= //
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnBlockingDiscoveryEnabled @ConditionalOnBlockingDiscoveryEnabled
@ConditionalOnClass(RetryTemplate.class) @ConditionalOnClass(RetryTemplate.class)
@ -208,6 +226,8 @@ public class LoadBalancerClientConfiguration {
} }
// ============================= Reactive Retry ============================= //
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@ConditionalOnReactiveDiscoveryEnabled @ConditionalOnReactiveDiscoveryEnabled
@Conditional(ReactiveOnAvoidPreviousInstanceAndRetryEnabledCondition.class) @Conditional(ReactiveOnAvoidPreviousInstanceAndRetryEnabledCondition.class)
@ -226,6 +246,7 @@ public class LoadBalancerClientConfiguration {
} }
// ============================= 条件类 ============================= //
static final class BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition extends AllNestedConditions { static final class BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition extends AllNestedConditions {
private BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition() { private BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition() {

6
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.blocking.client; package org.springframework.cloud.loadbalancer.blocking.client;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
@ -168,10 +168,14 @@ public class BlockingLoadBalancerClient implements LoadBalancerClient {
@Override @Override
public <T> ServiceInstance choose(String serviceId, Request<T> request) { public <T> ServiceInstance choose(String serviceId, Request<T> request) {
// ReactiveLoadBalancer 可以是 RoundRobinLoadBalancer,RandomLoadBalancer
// loadBalancerClientFactory继承NamedContextFactory,使用子容器实现隔离
ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory.getInstance(serviceId); ReactiveLoadBalancer<ServiceInstance> loadBalancer = loadBalancerClientFactory.getInstance(serviceId);
if (loadBalancer == null) { if (loadBalancer == null) {
return null; return null;
} }
// loadBalancer.choose,返回NacosServiceInstance
Response<ServiceInstance> loadBalancerResponse = Mono.from(loadBalancer.choose(request)).block(); Response<ServiceInstance> loadBalancerResponse = Mono.from(loadBalancer.choose(request)).block();
if (loadBalancerResponse == null) { if (loadBalancerResponse == null) {
return null; return null;

4
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.config; package org.springframework.cloud.loadbalancer.config;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -48,6 +48,7 @@ public class LoadBalancerAutoConfiguration {
private final ObjectProvider<List<LoadBalancerClientSpecification>> configurations; private final ObjectProvider<List<LoadBalancerClientSpecification>> configurations;
// 1. Spring 的特性,对于 Configuration ,其构造函数只有一个参数的时候,是可以自动注入的
public LoadBalancerAutoConfiguration(ObjectProvider<List<LoadBalancerClientSpecification>> configurations) { public LoadBalancerAutoConfiguration(ObjectProvider<List<LoadBalancerClientSpecification>> configurations) {
this.configurations = configurations; this.configurations = configurations;
} }
@ -62,6 +63,7 @@ public class LoadBalancerAutoConfiguration {
@Bean @Bean
public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) { public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) {
LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties); LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties);
// 【重要】这一步将配置类注入到 NamedContextFactory 中,实现个性化配置。
clientFactory.setConfigurations(this.configurations.getIfAvailable(Collections::emptyList)); clientFactory.setConfigurations(this.configurations.getIfAvailable(Collections::emptyList));
return clientFactory; return clientFactory;
} }

39
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.core; package org.springframework.cloud.loadbalancer.core;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -52,21 +52,28 @@ public class CachingServiceInstanceListSupplier extends DelegatingServiceInstanc
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, CacheManager cacheManager) { public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, CacheManager cacheManager) {
super(delegate); super(delegate);
this.serviceInstances = CacheFlux.lookup(key -> { // lookup的第一个入参:
// TODO: configurable cache name this.serviceInstances = CacheFlux
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); .lookup(key -> {
if (cache == null) { // TODO: configurable cache name
if (log.isErrorEnabled()) { Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
log.error("Unable to find cache: " + SERVICE_INSTANCE_CACHE_NAME); if (cache == null) {
} if (log.isErrorEnabled()) {
return Mono.empty(); log.error("Unable to find cache: " + SERVICE_INSTANCE_CACHE_NAME);
} }
List<ServiceInstance> list = cache.get(key, List.class); return Mono.empty();
if (list == null || list.isEmpty()) { }
return Mono.empty(); List<ServiceInstance> list = cache.get(key, List.class);
} if (list == null || list.isEmpty()) {
return Flux.just(list).materialize().collectList(); return Mono.empty();
}, delegate.getServiceId()).onCacheMissResume(delegate.get().take(1)) }
return Flux.just(list).materialize().collectList();
}, delegate.getServiceId()
)
// 【重要】cache miss时,获取原始数据。
// delegate 可以是 DiscoveryClientServiceInstanceListSupplier
.onCacheMissResume(delegate.get().take(1))
// 同时写入缓存
.andWriteWith((key, signals) -> Flux.fromIterable(signals).dematerialize().doOnNext(instances -> { .andWriteWith((key, signals) -> Flux.fromIterable(signals).dematerialize().doOnNext(instances -> {
Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME);
if (cache == null) { if (cache == null) {

22
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.core; package org.springframework.cloud.loadbalancer.core;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -74,14 +74,18 @@ public class DiscoveryClientServiceInstanceListSupplier implements ServiceInstan
public DiscoveryClientServiceInstanceListSupplier(ReactiveDiscoveryClient delegate, Environment environment) { public DiscoveryClientServiceInstanceListSupplier(ReactiveDiscoveryClient delegate, Environment environment) {
this.serviceId = environment.getProperty(PROPERTY_NAME); this.serviceId = environment.getProperty(PROPERTY_NAME);
resolveTimeout(environment); resolveTimeout(environment);
this.serviceInstances = Flux this.serviceInstances = Flux.defer(
.defer(() -> delegate.getInstances(serviceId).collectList().flux().timeout(timeout, Flux.defer(() -> { () -> delegate.getInstances(serviceId).collectList()
logTimeout(); .flux()
return Flux.just(new ArrayList<>()); .timeout(timeout, Flux.defer(() -> {
})).onErrorResume(error -> { logTimeout();
logException(error); return Flux.just(new ArrayList<>());
return Flux.just(new ArrayList<>()); }))
})); .onErrorResume(error -> {
logException(error);
return Flux.just(new ArrayList<>());
})
);
} }
@Override @Override

23
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java

@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.cloud.loadbalancer.core; package org.springframework.cloud.loadbalancer.core;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -46,6 +45,11 @@ public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalance
final String serviceId; final String serviceId;
/**
* 从LoadBalancerClientFactory中获取ServiceInstanceListSupplier类型的 bean
* 实际类型 ClientFactoryObjectProvider getLazyProvider 内的封装类
* @see org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory
*/
ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider; ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
/** /**
@ -77,21 +81,33 @@ public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalance
// https://github.com/Netflix/ocelli/blob/master/ocelli-core/ // https://github.com/Netflix/ocelli/blob/master/ocelli-core/
// src/main/java/netflix/ocelli/loadbalancer/RoundRobinLoadBalancer.java // src/main/java/netflix/ocelli/loadbalancer/RoundRobinLoadBalancer.java
public Mono<Response<ServiceInstance>> choose(Request request) { public Mono<Response<ServiceInstance>> choose(Request request) {
// 获取supplier,调用get方法获取List<ServiceInstance>
// 可以是 CachingServiceInstanceListSupplier 类型
// 也可以是自定义的ServiceInstanceListSupplier,这取决于调用的上下文。
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
// 相当于getOrDefault,实际返回 CachingServiceInstanceListSupplier
.getIfAvailable(NoopServiceInstanceListSupplier::new); .getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next() return supplier
// get的含义
.get(request)
// next方法:Flux转化为Mono
.next()
//
.map(serviceInstances -> processInstanceResponse(supplier, serviceInstances)); .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
} }
private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances) { List<ServiceInstance> serviceInstances) {
// 选择ServiceInstance
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances); Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
// 回调supplier,告知最终结果
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) { if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer()); ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
} }
return serviceInstanceResponse; return serviceInstanceResponse;
} }
// 轮询算法:在多个instances中选择一个
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) { private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) { if (instances.isEmpty()) {
if (log.isWarnEnabled()) { if (log.isWarnEnabled()) {
@ -100,6 +116,7 @@ public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalance
return new EmptyResponse(); return new EmptyResponse();
} }
// Ignore the sign bit, this allows pos to loop sequentially from 0 to // Ignore the sign bit, this allows pos to loop sequentially from 0 to
// Integer.MAX_VALUE // Integer.MAX_VALUE
int pos = this.position.incrementAndGet() & Integer.MAX_VALUE; int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;

9
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.core; package org.springframework.cloud.loadbalancer.core;
// comment-by-kai 源码阅读 spring cloud 2021.x
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -55,6 +55,7 @@ public final class ServiceInstanceListSupplierBuilder {
private static final Log LOG = LogFactory.getLog(ServiceInstanceListSupplierBuilder.class); private static final Log LOG = LogFactory.getLog(ServiceInstanceListSupplierBuilder.class);
// DiscoveryClientServiceInstanceListSupplier, 分为Blocking, Reactive两种.
private Creator baseCreator; private Creator baseCreator;
private DelegateCreator cachingCreator; private DelegateCreator cachingCreator;
@ -75,6 +76,7 @@ public final class ServiceInstanceListSupplierBuilder {
LOG.warn("Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator."); LOG.warn("Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator.");
} }
this.baseCreator = context -> { this.baseCreator = context -> {
// 构造Blocking DiscoveryClient
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class); DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment()); return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment());
@ -93,6 +95,9 @@ public final class ServiceInstanceListSupplierBuilder {
LOG.warn("Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator."); LOG.warn("Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator.");
} }
this.baseCreator = context -> { this.baseCreator = context -> {
// 构造Reactive DiscoveryClient
// 可以是ReactiveCompositeDiscoveryClient, 包含一个 NacosReactiveDiscoveryClient + SimpleReactiveDiscoveryClient
// 【重要】这里Nacos完成和LoadBalancer的集成
ReactiveDiscoveryClient discoveryClient = context.getBean(ReactiveDiscoveryClient.class); ReactiveDiscoveryClient discoveryClient = context.getBean(ReactiveDiscoveryClient.class);
return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment()); return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment());
@ -225,6 +230,7 @@ public final class ServiceInstanceListSupplierBuilder {
LOG.warn( LOG.warn(
"Overriding a previously set cachingCreator with a CachingServiceInstanceListSupplier-based cachingCreator."); "Overriding a previously set cachingCreator with a CachingServiceInstanceListSupplier-based cachingCreator.");
} }
// 启用Cache机制,使用CachingServiceInstanceListSupplier包装原始的ServiceInstanceListSupplier
this.cachingCreator = (context, delegate) -> { this.cachingCreator = (context, delegate) -> {
ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context ObjectProvider<LoadBalancerCacheManager> cacheManagerProvider = context
.getBeanProvider(LoadBalancerCacheManager.class); .getBeanProvider(LoadBalancerCacheManager.class);
@ -276,6 +282,7 @@ public final class ServiceInstanceListSupplierBuilder {
public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) { public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) {
Assert.notNull(baseCreator, "A baseCreator must not be null"); Assert.notNull(baseCreator, "A baseCreator must not be null");
// TODO context为什么是stock-service隔离的 ?
ServiceInstanceListSupplier supplier = baseCreator.apply(context); ServiceInstanceListSupplier supplier = baseCreator.apply(context);
for (DelegateCreator creator : creators) { for (DelegateCreator creator : creators) {

5
spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java

@ -15,7 +15,7 @@
*/ */
package org.springframework.cloud.loadbalancer.support; package org.springframework.cloud.loadbalancer.support;
// comment-by-kai 源码阅读 spring cloud 2021.x
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -64,7 +64,10 @@ public class LoadBalancerClientFactory extends NamedContextFactory<LoadBalancerC
this(null); this(null);
} }
// 构造器调用:org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration
public LoadBalancerClientFactory(LoadBalancerClientsProperties properties) { public LoadBalancerClientFactory(LoadBalancerClientsProperties properties) {
// 这里注意看 LoadBalancerClientConfiguration 被当成了默认配置类注入到 NamedContextFactory 中。也就是说每个子容器都会有这个配置类。
// 根据构造器 NamedContextFactory 会构造一个 PropertySource,key=loadbalancer.client.name,value = ?
super(LoadBalancerClientConfiguration.class, NAMESPACE, PROPERTY_NAME); super(LoadBalancerClientConfiguration.class, NAMESPACE, PROPERTY_NAME);
this.properties = properties; this.properties = properties;
} }

Loading…
Cancel
Save