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
中的配置类中查找 DiscoveryClient
和 ReactiveDiscoveryClient
的实现类 .
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应用向服务注册中心注册该实现类.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ConditionalOnProperty(
value = {"spring.cloud.discovery.blocking.enabled"},
matchIfMissing = true
)
public @interface ConditionalOnBlockingDiscoveryEnabled {
}
@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 {
}
@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
实现的顺序,其中包括ConsulDiscoveryClient
,EurekaDiscoveryClient
和ZookeeperDiscoveryClient
,为此,你只需将spring.cloud.{clientIdentifier}.discovery.order
(或Eureka的eureka.client.order
)属性设置为所需的值。
如果在类路径中没有支持从注册中心发现服务的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();
}
}
@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对应的服务发现的实现,以阻塞式DiscoveryClient为例
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();
}
}
}
@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);
}
}
@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);
}
}