DiscoveryClient
DiscoveryClient
接口定义了常见的服务发现操作,如获取服务实例、获取所有服务ID、验证客户端可用性等,通常用于 Eureka 或 Consul 等服务发现框架。
public interface DiscoveryClient extends Ordered {/*** Default order of the discovery client.*/int DEFAULT_ORDER = 0;/*** A human-readable description of the implementation, used in HealthIndicator.* @return The description.*/String description();/*** Gets all ServiceInstances associated with a particular serviceId.* @param serviceId The serviceId to query.* @return A List of ServiceInstance.*/List<ServiceInstance> getInstances(String serviceId);/*** @return All known service IDs.*/List<String> getServices();/*** Can be used to verify the client is valid and able to make calls.* <p>* A successful invocation with no exception thrown implies the client is able to make* calls.* <p>* The default implementation simply calls {@link #getServices()} - client* implementations can override with a lighter weight operation if they choose to.*/default void probe() {getServices();}/*** Default implementation for getting order of discovery clients.* @return order*/@Overridedefault int getOrder() {return DEFAULT_ORDER;}}
Simple
1. SimpleDiscoveryClientAutoConfiguration
SimpleDiscoveryClientAutoConfiguration
是 Spring Boot 自动配置类,基于配置文件属性创建一个简单的服务发现客户端。
/*** Spring Boot auto-configuration for simple properties-based discovery client.** @author Biju Kunjummen* @author Charu Covindane*/
@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore({ CommonsClientAutoConfiguration.class })
public class SimpleDiscoveryClientAutoConfiguration implements ApplicationListener<WebServerInitializedEvent> {private ServerProperties server;private InetUtils inet;private int port = 0;private SimpleDiscoveryProperties simple = new SimpleDiscoveryProperties();@Autowired(required = false)public void setServer(ServerProperties server) {this.server = server;}@Autowiredpublic void setInet(InetUtils inet) {this.inet = inet;}@Bean@ConditionalOnMissingBeanpublic SimpleDiscoveryProperties simpleDiscoveryProperties(@Value("${spring.application.name:application}") String serviceId) {simple.getLocal().setServiceId(serviceId);simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname());simple.getLocal().setPort(findPort());return simple;}@Bean@Orderpublic DiscoveryClient simpleDiscoveryClient(SimpleDiscoveryProperties properties) {return new SimpleDiscoveryClient(properties);}private int findPort() {if (port > 0) {return port;}if (server != null && server.getPort() != null && server.getPort() > 0) {return server.getPort();}return 8080;}@Overridepublic void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) {port = webServerInitializedEvent.getWebServer().getPort();if (port > 0) {simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname());simple.getLocal().setPort(port);}}}
2. SimpleDiscoveryClient
SimpleDiscoveryClient
是一个简单的 DiscoveryClient
实现,使用属性文件作为服务实例的来源,提供获取服务实例和服务列表的功能。
/*** A {@link org.springframework.cloud.client.discovery.DiscoveryClient} that will use the* properties file as a source of service instances.** @author Biju Kunjummen* @author Olga Maciaszek-Sharma* @author Charu Covindane*/
public class SimpleDiscoveryClient implements DiscoveryClient {private SimpleDiscoveryProperties simpleDiscoveryProperties;public SimpleDiscoveryClient(SimpleDiscoveryProperties simpleDiscoveryProperties) {this.simpleDiscoveryProperties = simpleDiscoveryProperties;}@Overridepublic String description() {return "Simple Discovery Client";}@Overridepublic List<ServiceInstance> getInstances(String serviceId) {List<ServiceInstance> serviceInstances = new ArrayList<>();List<DefaultServiceInstance> serviceInstanceForService = this.simpleDiscoveryProperties.getInstances().get(serviceId);if (serviceInstanceForService != null) {serviceInstances.addAll(serviceInstanceForService);}return serviceInstances;}@Overridepublic List<String> getServices() {return new ArrayList<>(this.simpleDiscoveryProperties.getInstances().keySet());}@Overridepublic int getOrder() {return this.simpleDiscoveryProperties.getOrder();}}
Composite
1. CompositeDiscoveryClientAutoConfiguration
CompositeDiscoveryClientAutoConfiguration
是一个自动配置类,负责创建并注入 CompositeDiscoveryClient
,将多个 DiscoveryClient
合并成一个客户端。
/*** Auto-configuration for composite discovery client.** @author Biju Kunjummen*/
@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore(SimpleDiscoveryClientAutoConfiguration.class)
public class CompositeDiscoveryClientAutoConfiguration {@Bean@Primarypublic CompositeDiscoveryClient compositeDiscoveryClient(List<DiscoveryClient> discoveryClients) {return new CompositeDiscoveryClient(discoveryClients);}}
2. CompositeDiscoveryClient
CompositeDiscoveryClient
是一个将多个 DiscoveryClient
组合在一起的客户端,它依次查询各个客户端获取服务实例,确保高可用性和灵活性。
public class CompositeDiscoveryClient implements DiscoveryClient {private final List<DiscoveryClient> discoveryClients;public CompositeDiscoveryClient(List<DiscoveryClient> discoveryClients) {AnnotationAwareOrderComparator.sort(discoveryClients);this.discoveryClients = discoveryClients;}@Overridepublic String description() {return "Composite Discovery Client";}@Overridepublic List<ServiceInstance> getInstances(String serviceId) {if (this.discoveryClients != null) {for (DiscoveryClient discoveryClient : this.discoveryClients) {List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);if (instances != null && !instances.isEmpty()) {return instances;}}}return Collections.emptyList();}@Overridepublic List<String> getServices() {LinkedHashSet<String> services = new LinkedHashSet<>();if (this.discoveryClients != null) {for (DiscoveryClient discoveryClient : this.discoveryClients) {List<String> serviceForClient = discoveryClient.getServices();if (serviceForClient != null) {services.addAll(serviceForClient);}}}return new ArrayList<>(services);}@Overridepublic void probe() {if (this.discoveryClients != null) {for (DiscoveryClient discoveryClient : this.discoveryClients) {discoveryClient.probe();}}}public List<DiscoveryClient> getDiscoveryClients() {return this.discoveryClients;}}
Nacos
Nacos是一个开源的动态服务发现、配置管理和服务管理平台,广泛用于微服务架构中的服务治理与配置管理。
1. NacosDiscoveryAutoConfiguration
NacosDiscoveryAutoConfiguration
类是一个 Spring 配置类,用于自动配置 Nacos 服务发现功能。它在 Nacos 服务发现启用时创建所需的 NacosDiscoveryProperties
和 NacosServiceDiscovery
Bean,并确保在没有其他相关 Bean 的情况下提供默认配置。
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
@ConditionalOnNacosDiscoveryEnabled
public class NacosDiscoveryAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic NacosDiscoveryProperties nacosProperties() {return new NacosDiscoveryProperties();}@Bean@ConditionalOnMissingBeanpublic NacosServiceDiscovery nacosServiceDiscovery(NacosDiscoveryProperties discoveryProperties, NacosServiceManager nacosServiceManager) {return new NacosServiceDiscovery(discoveryProperties, nacosServiceManager);}}
2. NacosDiscoveryClientConfiguration
NacosDiscoveryClientConfiguration
类用于配置和初始化 Nacos 服务发现客户端及其相关功能,如 DiscoveryClient
和 NacosWatch
。
@Configuration(proxyBeanMethods = false)
@ConditionalOnDiscoveryEnabled
@ConditionalOnBlockingDiscoveryEnabled
@ConditionalOnNacosDiscoveryEnabled
@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class })
@AutoConfigureAfter(NacosDiscoveryAutoConfiguration.class)
public class NacosDiscoveryClientConfiguration {@Beanpublic DiscoveryClient nacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {return new NacosDiscoveryClient(nacosServiceDiscovery);}/*** NacosWatch is no longer enabled by default .* see https://github.com/alibaba/spring-cloud-alibaba/issues/2868*/@Bean@ConditionalOnMissingBean@ConditionalOnProperty(value = "spring.cloud.nacos.discovery.watch.enabled", matchIfMissing = false)public NacosWatch nacosWatch(NacosServiceManager nacosServiceManager,NacosDiscoveryProperties nacosDiscoveryProperties) {return new NacosWatch(nacosServiceManager, nacosDiscoveryProperties);}}
3. NacosDiscoveryClient
NacosDiscoveryClient
实现了 DiscoveryClient
接口,通过与 Nacos 服务发现交互,提供获取服务实例和服务列表的功能,同时支持故障容错。
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;@Value("${spring.cloud.nacos.discovery.failure-tolerance-enabled:false}")private boolean failureToleranceEnabled;public NacosDiscoveryClient(NacosServiceDiscovery nacosServiceDiscovery) {this.serviceDiscovery = nacosServiceDiscovery;}@Overridepublic String description() {return DESCRIPTION;}@Overridepublic List<ServiceInstance> getInstances(String serviceId) {try {return Optional.of(serviceDiscovery.getInstances(serviceId)).map(instances -> {ServiceCache.setInstances(serviceId, instances);return instances;}).get();}catch (Exception e) {if (failureToleranceEnabled) {return ServiceCache.getInstances(serviceId);}throw new RuntimeException("Can not get hosts from nacos server. serviceId: " + serviceId, e);}}@Overridepublic List<String> getServices() {try {return Optional.of(serviceDiscovery.getServices()).map(services -> {ServiceCache.setServiceIds(services);return services;}).get();}catch (Exception e) {log.error("get service name from nacos server failed.", e);return failureToleranceEnabled ? ServiceCache.getServiceIds(): Collections.emptyList();}}}