spring-cloud-commons之DiscoveryClient

谭修竹
2023-12-01

DiscoveryClient接口

public interface DiscoveryClient extends Ordered {
    int DEFAULT_ORDER = 0;

    String description();

    List<ServiceInstance> getInstances(String serviceId);

    List<String> getServices();

    default int getOrder() {
        return 0;
    }
}

@EnableDiscoveryClient注解

Spring Cloud Commons 提供了@EnableDiscoveryClient 注解. 其会在META-INF/spring.factories中的配置类中查找 DiscoveryClientReactiveDiscoveryClient 的实现类 .

Spring Cloud默认提供了阻塞式和响应式服务发现客户端.

你可以通过设置 spring.cloud.discovery.blocking.enabled=false 禁用阻塞式客户端,

通过设置spring.cloud.discovery.reactive.enabled=false禁用响应式客户端.

也可以通过设置 spring.cloud.discovery.enabled=false完全的禁用服务发现.

默认情况下, DiscoveryClient 实现类会自动注册本地Spring Boot 服务到远程服务注册中心. 可以通过设置 @EnableDiscoveryClient里的autoRegister=false来禁用这一行为.

@EnableDiscoveryClient 已不再是必须的. 你可以把DiscoveryClient 实现类放到classpath路径下使Spring Boot应用向服务注册中心注册该实现类.

@ConditionalOnBlockingDiscoveryEnabled

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnProperty(
    value = {"spring.cloud.discovery.blocking.enabled"},
    matchIfMissing = true
)
public @interface ConditionalOnBlockingDiscoveryEnabled {
}

@ConditionalOnReactiveDiscoveryEnabled注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnClass(
    name = {"org.springframework.web.reactive.function.client.WebClient"}
)
@ConditionalOnProperty(
    value = {"spring.cloud.discovery.reactive.enabled"},
    matchIfMissing = true
)
public @interface ConditionalOnReactiveDiscoveryEnabled {
}

@ConditionalOnDiscoveryEnabled注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnProperty(
    value = {"spring.cloud.discovery.enabled"},
    matchIfMissing = true
)
public @interface ConditionalOnDiscoveryEnabled {
}

DiscoveryClient 实现类排序

DiscoveryClient接口扩展了Ordered,这在使用多个发现客户端时很有用,因为它允许你定义返回的发现客户端的顺序,类似于你可以如何排序Spring应用程序加载的bean。默认情况下,任何DiscoveryClient的顺序都设置为0,如果要为自定义DiscoveryClient实现设置不同的顺序,只需重写getOrder()方法,以便它返回适合你的设置的值。除此之外,你还可以使用属性来设置Spring Cloud提供的DiscoveryClient实现的顺序,其中包括ConsulDiscoveryClientEurekaDiscoveryClientZookeeperDiscoveryClient,为此,你只需将spring.cloud.{clientIdentifier}.discovery.order(或Eureka的eureka.client.order)属性设置为所需的值。

SimpleDiscoveryClient

如果在类路径中没有支持从注册中心发现服务的DiscoveryClient实现类,则将使用SimpleDiscoveryClient实例,该实例使用SimpleDiscoveryProperties来获取有关服务和实例的信息。

可用的实例的配置信息格式为: spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080

spring.cloud.discovery.client.simple.instances 是公共前缀,

service1 表示服务ID, [0] 表示服务实例的下标,下标从0开始,

uri 是可用的服务实例的真实URI.

public class SimpleDiscoveryClient implements DiscoveryClient {
    private SimpleDiscoveryProperties simpleDiscoveryProperties;
 
    public SimpleDiscoveryClient(SimpleDiscoveryProperties simpleDiscoveryProperties) {
        this.simpleDiscoveryProperties = simpleDiscoveryProperties;
    }
 
    public String description() {
        return "Simple Discovery Client";
    }
 
    public List<ServiceInstance> getInstances(String serviceId) {
        List<ServiceInstance> serviceInstances = new ArrayList();
        List<DefaultServiceInstance> serviceInstanceForService = (List)this.simpleDiscoveryProperties.getInstances().get(serviceId);
        if (serviceInstanceForService != null) {
            serviceInstances.addAll(serviceInstanceForService);
        }
 
        return serviceInstances;
    }
 
    public List<String> getServices() {
        return new ArrayList(this.simpleDiscoveryProperties.getInstances().keySet());
    }
 
    public int getOrder() {
        return this.simpleDiscoveryProperties.getOrder();
    }
}

SimpleDiscoveryProperties 服务实例的属性配置

@ConfigurationProperties(
    prefix = "spring.cloud.discovery.client.simple"
)
public class SimpleDiscoveryProperties {
    //在配置文件中配置的实例属性
    private Map<String, List<DefaultServiceInstance>> instances = new HashMap();
    private DefaultServiceInstance local = new DefaultServiceInstance((String)null, (String)null, (String)null, 0, false);
    private int order = 0;
}

Nacos对应的实现

下面是Nacos对应的服务发现的实现,以阻塞式DiscoveryClient为例

NacosDiscoveryClient

NacosDiscoveryClient是Nacos对DiscoveryClient的实现

public class NacosDiscoveryClient implements DiscoveryClient {
    private static final Logger log = LoggerFactory.getLogger(NacosDiscoveryClient.class);
    public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";
    private NacosServiceDiscovery serviceDiscovery;

    public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
        this.serviceDiscovery = nacosServiceDiscovery;
    }

    public String description() {
        return "Spring Cloud Nacos Discovery Client";
    }

    public List<ServiceInstance> getInstances(String serviceId) {
        try {
            return this.serviceDiscovery.getInstances(serviceId);
        } catch (Exception var3) {
            throw new RuntimeException("Can not get hosts from nacos server. serviceId: " + serviceId, var3);
        }
    }

    public List<String> getServices() {
        try {
            return this.serviceDiscovery.getServices();
        } catch (Exception var2) {
            log.error("get service name from nacos server fail,", var2);
            return Collections.emptyList();
        }
    }
}

NacosDiscoveryAutoConfiguration

@Configuration(
    proxyBeanMethods = false
)
//spring-cloud-common中定义的服务发现条件注解
@ConditionalOnDiscoveryEnabled
//nacos定义的Nacos服务发现条件注解
@ConditionalOnNacosDiscoveryEnabled
public class NacosDiscoveryAutoConfiguration {
    public NacosDiscoveryAutoConfiguration() {
    }
    //Nacos服务发现配置属性
    @Bean
    @ConditionalOnMissingBean
    public NacosDiscoveryProperties nacosProperties() {
        return new NacosDiscoveryProperties();
    }
    //Nacos服务发现service,为NacosDiscoveryClient提供真实的服务实例
    @Bean
    @ConditionalOnMissingBean
    public NacosServiceDiscovery nacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) {
        return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager);
    }
}

NacosDiscoveryClientConfiguration

@Configuration(
    proxyBeanMethods = false
)
//spring-cloud-common中定义的服务发现条件注解
@ConditionalOnDiscoveryEnabled
//spring-cloud-common中定义的阻塞式服务发现条件注解
@ConditionalOnBlockingDiscoveryEnabled
//nacos定义的Nacos服务发现条件注解
@ConditionalOnNacosDiscoveryEnabled
//SimpleDiscoveryClientAutoConfiguration注解是SimpleDiscoveryClient客户端实现配置
//由此可以看出,只要由其他的DiscoveryClient,就不会使用SimpleDiscoveryClient
@AutoConfigureBefore({SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class})
@AutoConfigureAfter({NacosDiscoveryAutoConfiguration.class})
public class NacosDiscoveryClientConfiguration {
    public NacosDiscoveryClientConfiguration() {
    }
    //Nacos实现的DiscoveryClient
    @Bean
    public DiscoveryClient nacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {
        return new NacosDiscoveryClient(nacosServiceDiscovery);
    }
    //Nacos的监听实现
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        value = {"spring.cloud.nacos.discovery.watch.enabled"},
        matchIfMissing = true
    )
    public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager, NacosDiscoveryProperties nacosDiscoveryProperties) {
        return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties);
    }
}

 类似资料: