一 概述
Eureka Client通过Starter的方式引入依赖,Spring Boot将会为项目使不同的注解进行自动配置。
- EurekaClientAutoConfiguration:Eureka Client自动配置类,负责Eureka Client中关键Beans的配置和初始化,如ApplicationInfoManager和EurekaClientConfig等。
- RibbonEurekaAutoConfiguration:Ribbon负载均衡相关配置。
- EurekaDiscoveryClientConfiguratino:配置自动注册和应用的健康检查器。
二 Eureka Client的完整工作流程
应用启动阶段
- 读取与Eureka Server交互的配置信息,封装成EurekaClientConfig。
- 读取自身服务实例配置信息,封装成EurekaInstanceConfig。
- 从Eureka Server中拉取注册表信息并缓存到本地。
- 服务注册。
- 初始化发送心跳,缓存刷新(拉取注册表信息更新本地缓存)和按需注册(监控服务实例信息变化,决定是否重新发起注册,更新注册表中的服务实例元数据)定时任务。
应用执行阶段
- 定时发送心跳到Eureka Server中,维持在注册表的租约。
- 定时从Eureka Server中拉取注册表信息,更新本地注册表缓存。
- 监控一个用自身信息变化,若发生变化,需要重新发起服务注册。
应用销毁阶段
- 从Eureka Server注销自身服务实例。
三 配置类EurekaDiscoveryClientConfiguration
源码
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@ConditionalOnDiscoveryEnabled
@ConditionalOnBlockingDiscoveryEnabled
public class EurekaDiscoveryClientConfiguration {
@Bean
@ConditionalOnMissingBean
public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) {
return new EurekaDiscoveryClient(client, clientConfig);
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
protected static class EurekaHealthCheckHandlerConfiguration {
@Autowired(required = false)
private StatusAggregator statusAggregator = new SimpleStatusAggregator();
@Bean
@ConditionalOnMissingBean(HealthCheckHandler.class)
public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
return new EurekaHealthCheckHandler(this.statusAggregator);
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
protected static class EurekaClientConfigurationRefresher
implements ApplicationListener<RefreshScopeRefreshedEvent> {
@Autowired(required = false)
private EurekaClient eurekaClient;
@Autowired(required = false)
private EurekaAutoServiceRegistration autoRegistration;
public void onApplicationEvent(RefreshScopeRefreshedEvent event) {
// This will force the creation of the EurkaClient bean if not already created
// to make sure the client will be reregistered after a refresh event
if (eurekaClient != null) {
eurekaClient.getApplications();
}
if (autoRegistration != null) {
// register in case meta data changed
this.autoRegistration.stop();
this.autoRegistration.start();
}
}
}
}
EurekaDiscoveryClientConfiguration中属性读取和配置类
类名 | 作用和介绍 |
EurekaClientConfig | 封装Eureka Client与Eureka Server交互所需要的配置信息。Spring Cloud为其提供了一个默认配置Eureka的配置类EurekaClientConfigBean,可以在配置文件中通过前缀eureka.client + 属性名进行属性覆盖。 |
ApplicationInfoManager | 作为应用信息管理,管理服务实例的信息类InstanceInfo和服务实例的配置信息类EurekaInstanceConfig。 |
InstanceInfo | 封装将被发送到Eureka Server进行服务注册和服务实例元数据。它在Eureka Server的注册表中代表一个服务实例,其他服务实例可以通过InstanceInfo了解该服务实例的相关信息从而发起服务请求。 |
EurekaInstanceConfig | 封装Eureka Client自身服务实例的配置信息,主要用于构建InstanceInfo,通常这些信息在配置文件中的eureka.instance前缀下进行设置,Spring Cloud通过EurekaInstanceConfigBean配置类提供了默认配置。 |
DiscoveryClient | Spring Cloud中定义用来服务发现的客户端接口。 |
默认配置类EurekaClientConfigBean的部分信息源码
@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
public class EurekaClientConfigBean implements EurekaClientConfig, Ordered {
public static final String PREFIX = "eureka.client";
public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX + "/";
public static final String DEFAULT_ZONE = "defaultZone";
private static final int MINUTES = 60;
@Autowired(required = false)
PropertyResolver propertyResolver;
private boolean enabled = true;
@NestedConfigurationProperty
private EurekaTransportConfig transport = new CloudEurekaTransportConfig();
private int registryFetchIntervalSeconds = 30;
private int instanceInfoReplicationIntervalSeconds = 30;
private int initialInstanceInfoReplicationIntervalSeconds = 40;
private int eurekaServiceUrlPollIntervalSeconds = 5 * MINUTES;
private String proxyPort;
private String proxyHost;
private String proxyUserName;
private String proxyPassword;
private int eurekaServerReadTimeoutSeconds = 8;
private int eurekaServerConnectTimeoutSeconds = 5;
private String backupRegistryImpl;
private int eurekaServerTotalConnections = 200;
private int eurekaServerTotalConnectionsPerHost = 50;
private String eurekaServerURLContext;
private String eurekaServerPort;
private String eurekaServerDNSName;
private String region = "us-east-1";
private int eurekaConnectionIdleTimeoutSeconds = 30;
private String registryRefreshSingleVipAddress;
private int heartbeatExecutorThreadPoolSize = 2;
private int heartbeatExecutorExponentialBackOffBound = 10;
private int cacheRefreshExecutorThreadPoolSize = 2;
private int cacheRefreshExecutorExponentialBackOffBound = 10;
private Map<String, String> serviceUrl = new HashMap<>();
{
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
}
private boolean gZipContent = true;
private boolean useDnsForFetchingServiceUrls = false;
private boolean registerWithEureka = true;
private boolean preferSameZoneEureka = true;
private boolean logDeltaDiff;
private boolean disableDelta;
private String fetchRemoteRegionsRegistry;
private Map<String, String> availabilityZones = new HashMap<>();
private boolean filterOnlyUpInstances = true;
private boolean fetchRegistry = true;
private String dollarReplacement = "_-";
private String escapeCharReplacement = "__";
private boolean allowRedirects = false;
private boolean onDemandUpdateStatusChange = true;
private String encoderName;
private String decoderName;
private String clientDataAccept = EurekaAccept.full.name();
private boolean shouldUnregisterOnShutdown = true;
private boolean shouldEnforceRegistrationAtInit = false;
private int order = 0;
}
继续复习总结中,待续!