Spring Cloud Eureka -2 Eureka client(1)

几个重要的类 :
EurekaClientAutoConfiguration
EurekaInstanceConfigBean
EurekaClientConfigBean
EurekaDiscoveryClient-CloudEurekaClient-DiscoveryClient
EurekaServiceRegistry
EurekaRegistration
EurekaAutoServiceRegistration

自动装配类
EurekaClientAutoConfiguration Eureka 自动装配类。

@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@Import(DiscoveryClientOptionalArgsConfiguration.class)
@ConditionalOnBean(EurekaDiscoveryClientConfiguration.Marker.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
        CommonsClientAutoConfiguration.class, ServiceRegistryAutoConfiguration.class })
@AutoConfigureAfter(name = {"org.springframework.cloud.autoconfigure.RefreshAutoConfiguration",
        "org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration",
        "org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration"})
public class EurekaClientAutoConfiguration {

ManagementMetadataProvider - (元数据与默认配置的思想)
监控元数据提供类,提供默认的实现,用来处理健康检查和状态页面地址的封装类。

    @Bean
    @ConditionalOnMissingBean
    public ManagementMetadataProvider serviceManagementMetadataProvider() {
        return new DefaultManagementMetadataProvider();
    }

注入EurekaInstanceConfigBean,Eureka的实例配置类

    @Bean
    @ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
    public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,
                                                             ManagementMetadataProvider managementMetadataProvider) {

InetUtils inetUtils 由UtilAutoConfiguration注入。
eureka.instance的配置说明:

#服务注册中心实例的主机名  
eureka.instance.hostname=localhost  
#注册在Eureka服务中的应用组名  
eureka.instance.app-group-name=  
#注册在的Eureka服务中的应用名称  
eureka.instance.appname=  
#该实例注册到服务中心的唯一ID  
eureka.instance.instance-id=  
#该实例的IP地址  
eureka.instance.ip-address=  
#该实例,相较于hostname是否优先使用IP  
eureka.instance.prefer-ip-address=false  
#用于AWS平台自动扩展的与此实例关联的组名,  
eureka.instance.a-s-g-name=  
#部署此实例的数据中心  
eureka.instance.data-center-info=  
#默认的地址解析顺序  
eureka.instance.default-address-resolution-order=  
#该实例的环境配置  
eureka.instance.environment=  
#初始化该实例,注册到服务中心的初始状态  
eureka.instance.initial-status=up  
#表明是否只要此实例注册到服务中心,立马就进行通信  
eureka.instance.instance-enabled-onit=false  
#该服务实例的命名空间,用于查找属性  
eureka.instance.namespace=eureka  
#该服务实例的子定义元数据,可以被服务中心接受到  
eureka.instance.metadata-map.test = test
#服务中心删除此服务实例的等待时间(秒为单位),时间间隔为最后一次服务中心接受到的心跳时间  
eureka.instance.lease-expiration-duration-in-seconds=90  
#该实例给服务中心发送心跳的间隔时间,用于表明该服务实例可用  
eureka.instance.lease-renewal-interval-in-seconds=30  
#该实例,注册服务中心,默认打开的通信数量  
eureka.instance.registry.default-open-for-traffic-count=1  
#每分钟续约次数  
eureka.instance.registry.expected-number-of-renews-per-min=1  
#该实例健康检查url,绝对路径  
eureka.instance.health-check-url=  
#该实例健康检查url,相对路径  
eureka.instance.health-check-url-path=/health  
#该实例的主页url,绝对路径  
eureka.instance.home-page-url=  
#该实例的主页url,相对路径  
eureka.instance.home-page-url-path=/  
#该实例的安全健康检查url,绝对路径  
eureka.instance.secure-health-check-url=  
#https通信端口  
eureka.instance.secure-port=443  
#https通信端口是否启用  
eureka.instance.secure-port-enabled=false  
#http通信端口  
eureka.instance.non-secure-port=80  
#http通信端口是否启用  
eureka.instance.non-secure-port-enabled=true  
#该实例的安全虚拟主机名称(https)  
eureka.instance.secure-virtual-host-name=unknown  
#该实例的虚拟主机名称(http)  
eureka.instance.virtual-host-name=unknown  
#该实例的状态呈现url,绝对路径  
eureka.instance.status-page-url=  
#该实例的状态呈现url,相对路径  
eureka.instance.status-page-url-path=/status

注入EurekaClientConfigBean

   @Bean
    @ConditionalOnMissingBean(value = EurekaClientConfig.class, search = SearchStrategy.CURRENT)
    public EurekaClientConfigBean eurekaClientConfigBean(ConfigurableEnvironment env) {
        EurekaClientConfigBean client = new EurekaClientConfigBean();
        if ("bootstrap".equals(this.env.getProperty("spring.config.name"))) {
            // We don't register during bootstrap by default, but there will be another
            // chance later.
            client.setRegisterWithEureka(false);
        }
        return client;
    }

eureka.client 配置

#该客户端是否可用,默认为true  
eureka.client.enabled=true  
#实例是否在eureka服务器上注册自己的信息以供其他服务发现,默认为true  
eureka.client.register-with-eureka=false  
#此客户端是否获取eureka服务器注册表上的注册信息,默认为true  
eureka.client.fetch-registry=false  
#是否过滤掉,非UP的实例。默认为true  
eureka.client.filter-only-up-instances=true  
#与Eureka注册服务中心的通信zone和url地址  
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/  
  
#client连接Eureka服务端后的空闲等待时间,默认为30 秒  
eureka.client.eureka-connection-idle-timeout-seconds=30  
#client连接eureka服务端的连接超时时间,默认为5秒  
eureka.client.eureka-server-connect-timeout-seconds=5  
#client对服务端的读超时时长  
eureka.client.eureka-server-read-timeout-seconds=8  
#client连接all eureka服务端的总连接数,默认200  
eureka.client.eureka-server-total-connections=200  
#client连接eureka服务端的单机连接数量,默认50  
eureka.client.eureka-server-total-connections-per-host=50  
#执行程序指数回退刷新的相关属性,是重试延迟的最大倍数值,默认为10  
eureka.client.cache-refresh-executor-exponential-back-off-bound=10  
#执行程序缓存刷新线程池的大小,默认为5  
eureka.client.cache-refresh-executor-thread-pool-size=2  
#心跳执行程序回退相关的属性,是重试延迟的最大倍数值,默认为10  
eureka.client.heartbeat-executor-exponential-back-off-bound=10  
#心跳执行程序线程池的大小,默认为5  
eureka.client.heartbeat-executor-thread-pool-size=5  
# 询问Eureka服务url信息变化的频率(s),默认为300秒  
eureka.client.eureka-service-url-poll-interval-seconds=300  
#最初复制实例信息到eureka服务器所需的时间(s),默认为40秒  
eureka.client.initial-instance-info-replication-interval-seconds=40  
#间隔多长时间再次复制实例信息到eureka服务器,默认为30秒  
eureka.client.instance-info-replication-interval-seconds=30  
#从eureka服务器注册表中获取注册信息的时间间隔(s),默认为30秒  
eureka.client.registry-fetch-interval-seconds=30  
  
# 获取实例所在的地区。默认为us-east-1  
eureka.client.region=us-east-1  
#实例是否使用同一zone里的eureka服务器,默认为true,理想状态下,eureka客户端与服务端是在同一zone下  
eureka.client.prefer-same-zone-eureka=true  
# 获取实例所在的地区下可用性的区域列表,用逗号隔开。(AWS)  
eureka.client.availability-zones.china=defaultZone,defaultZone1,defaultZone2  
#eureka服务注册表信息里的以逗号隔开的地区名单,如果不这样返回这些地区名单,则客户端启动将会出错。默认为null  
eureka.client.fetch-remote-regions-registry=  
#服务器是否能够重定向客户端请求到备份服务器。 如果设置为false,服务器将直接处理请求,如果设置为true,它可能发送HTTP重定向到客户端。默认为false  
eureka.client.allow-redirects=false  
#客户端数据接收  
eureka.client.client-data-accept=  
#增量信息是否可以提供给客户端看,默认为false  
eureka.client.disable-delta=false  
#eureka服务器序列化/反序列化的信息中获取“_”符号的的替换字符串。默认为“__“  
eureka.client.escape-char-replacement=__  
#eureka服务器序列化/反序列化的信息中获取“$”符号的替换字符串。默认为“_-”  
eureka.client.dollar-replacement="_-"  
#当服务端支持压缩的情况下,是否支持从服务端获取的信息进行压缩。默认为true  
eureka.client.g-zip-content=true  
#是否记录eureka服务器和客户端之间在注册表的信息方面的差异,默认为false  
eureka.client.log-delta-diff=false  
# 如果设置为true,客户端的状态更新将会点播更新到远程服务器上,默认为true  
eureka.client.on-demand-update-status-change=true  
#此客户端只对一个单一的VIP注册表的信息感兴趣。默认为null  
eureka.client.registry-refresh-single-vip-address=  
#client是否在初始化阶段强行注册到服务中心,默认为false  
eureka.client.should-enforce-registration-at-init=false  
#client在shutdown的时候是否显示的注销服务从服务中心,默认为true  
eureka.client.should-unregister-on-shutdown=true  
  
# 获取eureka服务的代理主机,默认为null  
eureka.client.proxy-host=  
#获取eureka服务的代理密码,默认为null  
eureka.client.proxy-password=  
# 获取eureka服务的代理端口, 默认为null  
eureka.client.proxy-port=  
# 获取eureka服务的代理用户名,默认为null  
eureka.client.proxy-user-name=  
  
#属性解释器  
eureka.client.property-resolver=  
#获取实现了eureka客户端在第一次启动时读取注册表的信息作为回退选项的实现名称  
eureka.client.backup-registry-impl=  
#这是一个短暂的×××的配置,如果最新的×××是稳定的,则可以去除,默认为null  
eureka.client.decoder-name=  
#这是一个短暂的编码器的配置,如果最新的编码器是稳定的,则可以去除,默认为null  
eureka.client.encoder-name=  
  
#是否使用DNS机制去获取服务列表,然后进行通信。默认为false  
eureka.client.use-dns-for-fetching-service-urls=false  
#获取要查询的DNS名称来获得eureka服务器,此配置只有在eureka服务器ip地址列表是在DNS中才会用到。默认为null  
eureka.client.eureka-server-d-n-s-name=  
#获取eureka服务器的端口,此配置只有在eureka服务器ip地址列表是在DNS中才会用到。默认为null  
eureka.client.eureka-server-port=  
#表示eureka注册中心的路径,如果配置为eureka,则为http://x.x.x.x:x/eureka/,在eureka的配置文件中加入此配置表示eureka作为客户端向注册中心注册,从而构成eureka集群。此配置只有在eureka服务器ip地址列表是在DNS中才会用到,默认为null  
eureka.client.eureka-server-u-r-l-context=  

注入EurekaDiscoveryClient, 持有CloudEurekaClient,CloudEurekaClient是SpringCloud对Eureka客户端的封装。
在RefreshableEurekaClientConfiguration中对CloudEurekaClient进行注入,也就是对DiscoveryClient的初始化,客户端向服务端注册。
DiscoveryClient构造方法主要逻辑:

        // 是否向服务端注册是否获取服务端的注册列表
        if (!config.shouldRegisterWithEureka() && !config.shouldFetchRegistry()) {
            logger.info("Client configured to neither register nor query for data.");
// default size of 2 - 1 each for heartbeat and cacheRefresh
// 执行定时任务的定时器,定时线程名为 DiscoveryClient-%
 // 在定时器中用于定时执行TimedSupervisorTask监督任务,监督任务会强制超时 和 记录监控数据scheduler = Executors.newScheduledThreadPool(2,
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-%d")
                            .setDaemon(true)
                            .build());

// 心跳线程池
heartbeatExecutor = new ThreadPoolExecutor(
                    1, clientConfig.getHeartbeatExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-HeartbeatExecutor-%d")
                            .setDaemon(true)
                            .build()
            );  // use direct handoff
// 缓存刷新线程池
            cacheRefreshExecutor = new ThreadPoolExecutor(
                    1, clientConfig.getCacheRefreshExecutorThreadPoolSize(), 0, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    new ThreadFactoryBuilder()
                            .setNameFormat("DiscoveryClient-CacheRefreshExecutor-%d")
                            .setDaemon(true)
                            .build()
            );  // use direct handoff
初始化内部类EurekaTransport,该类用于向EurekaServer发送请求。
eurekaTransport = new EurekaTransport();
            scheduleServerEndpointTask(eurekaTransport, args);
// 如果需要从eureka server获取服务列表,并且尝试fetchRegistry(false)失败,调用BackupRegistry
    if (clientConfig.shouldFetchRegistry() && !fetchRegistry(false)) {
        fetchRegistryFromBackup();
    }
    // 初始化所有定时任务
    initScheduledTasks();
图片.png
@Bean
    public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
        return new EurekaDiscoveryClient(config, client);
    }

初始化EurekaServiceRegistry对象,EurekaServiceRegistry实现了ServiceRegistry接口,服务注册相关接口。ServiceRegistry是Spring定义的服务注册接口。

@Bean
    public EurekaServiceRegistry eurekaServiceRegistry() {
        return new EurekaServiceRegistry();
    }

通过EurekaServiceRegistry,进行:
服务注册 register(EurekaRegistration reg) -- 使用监听器模式,以下同理。
服务注销deregister(EurekaRegistration reg) - 设置服务实例状态为DOWN
设置当前实例服务状态setStatus(EurekaRegistration registration, String status)- 可用于服务的优雅下线。
获取当前实例服务状态getStatus(EurekaRegistration registration) - UP DOWN OUT_OF_SERVICE UNKOWN。参考:InstanceStatus

EurekaServiceRegistry依赖EurekaRegistration,EurekaRegistration代表当前服务实例。

public class EurekaRegistration implements Registration {
    private static final Log log = LogFactory.getLog(EurekaRegistration.class);

    private final EurekaClient eurekaClient;
    private final AtomicReference<CloudEurekaClient> cloudEurekaClient = new AtomicReference<>();
    private final CloudEurekaInstanceConfig instanceConfig;
    private final ApplicationInfoManager applicationInfoManager;
    private ObjectProvider<HealthCheckHandler> healthCheckHandler;

持有配置对象、应用信息管理类ApplicationInfoManager,The class that initializes information required for registration with Eureka Server and to be discovered by other components. 提供被Eureka Server 服务注册发现的注册信息。

EurekaAutoServiceRegistration实现SmartLifecycle接口,被Spring容器管理,start()方法发布事件,stop() 方法注销服务实例。也监听WebServerInitializedEvent,ContextClosedEvent事件。

@Bean
    @ConditionalOnBean(AutoServiceRegistrationProperties.class)
    @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
    public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry,
                                                                       EurekaRegistration registration) {
        return new EurekaAutoServiceRegistration(context, registry, registration);
    }

参考:
https://www.cnblogs.com/trust-freedom/p/10218145.html
https://www.cnblogs.com/trust-freedom/p/10310606.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。