SpringCloud-Eureka-服务注册是如何发起的
Spring Cloud环境下,服务提供者和消费者启动后都会将自身注册到Eureka
一、将服务注册到Eureka
一个SpringBoot应用如果要注册到Spring Cloud环境(Greenwich.SR3版本),步骤很简单:
pom.xml中添加启动器:spring-cloud-starter-netflix-eureka-client;
增加配置:eureka.client.serviceUrl.defaultZone: http://localhost:8100/eureka/;
启动应用;
如果注册中心正常,此时就能在注册中心发现这个应用了,如下图红框所示:

按照spring.factories中的配置,EurekaClientAutoConfiguration中的配置都会生效,包括下面这段代码返回的bean:
@Bean
public DiscoveryClient discoveryClient(EurekaInstanceConfig config, EurekaClient client) {
return new EurekaDiscoveryClient(config, client);
}
spring容器初始化时会实例化所有单例bean,就会执行EurekaClientAutoConfiguration的discoveryClient方法获取这个bean实例,于是就构造了一个EurekaDiscoveryClient对象;
注意EurekaDiscoveryClient的构造方法,第二个入参是com.netflix.discovery.EurekaClient类型,此对象同样来自EurekaClientAutoConfiguration类,如下方法:
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
@org.springframework.cloud.context.config.annotation.RefreshScope
@Lazy
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance) {
manager.getInfo(); // force initialization
return new CloudEurekaClient(manager, config, this.optionalArgs,this.context);
}
CloudEurekaClient的父类com.netflix.discovery.DiscoveryClient来自netflix发布的eureka-client包中,所以可以这么理解:EurekaDiscoveryClient类是个代理身份,真正的服务注册发现是委托给netflix的开源包来完成的,我们可以专心的使用SpringCloud提供的服务注册发现功能,只需要知道EurekaDiscoveryClient即可,真正的服务是eureka-client来完成的;
接下来需要关注com.netflix.discovery.DiscoveryClient的构造方法,因为这里面有服务注册的逻辑,整个构造方法内容太多,无需都细看,只看关键代码即可;
DiscoveryClient的构造方法中,最熟悉的应该是下图红框中这段日志输出的了:
对应的应用启动日志中就有这段日志输出,如下图红框:

红框中的”us-east-1”,是默认的region,来自配置类EurekaClientConfigBean,这里面有各种eureka相关的配置信息,以及默认配置,如下图:

继续看DiscoveryClient的构造方法,服务注册相关的initScheduledTasks方法在此被调用,如下图:

initScheduledTasks方法的内容如下,请注意中文注释:
private void initScheduledTasks() {
//获取服务注册列表信息
if (clientConfig.shouldFetchRegistry()) {
//服务注册列表更新的周期时间
int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
//定时更新服务注册列表
scheduler.schedule(
new TimedSupervisorTask(
"cacheRefresh",
scheduler,
cacheRefreshExecutor,
registryFetchIntervalSeconds,
TimeUnit.SECONDS,
expBackOffBound,
new CacheRefreshThread() //该线程执行更新的具体逻辑
),
registryFetchIntervalSeconds, TimeUnit.SECONDS);
}
if (clientConfig.shouldRegisterWithEureka()) {
//服务续约的周期时间
int renewalIntervalInSecs = instanceInfo.getLeaseInfo().getRenewalIntervalInSecs();
int expBackOffBound = clientConfig.getHeartbeatExecutorExponentialBackOffBound();
//应用启动可见此日志,内容是:Starting heartbeat executor: renew interval is: 30
logger.info("Starting heartbeat executor: " + "renew interval is: " + renewalIntervalInSecs);
// 定时续约
scheduler.schedule(
new TimedSupervisorTask(
"heartbeat",
scheduler,
heartbeatExecutor,
renewalIntervalInSecs,
TimeUnit.SECONDS,
expBackOffBound,
new HeartbeatThread() //该线程执行续约的具体逻辑
),
renewalIntervalInSecs, TimeUnit.SECONDS); //这个Runable中含有服务注册的逻辑
instanceInfoReplicator = new InstanceInfoReplicator(
this,
instanceInfo,
clientConfig.getInstanceInfoReplicationIntervalSeconds(),
2); // burstSize statusChangeListener = new ApplicationInfoManager.StatusChangeListener() {
@Override
public String getId() {
return "statusChangeListener";
} @Override
public void notify(StatusChangeEvent statusChangeEvent) {
if (InstanceStatus.DOWN == statusChangeEvent.getStatus() ||
InstanceStatus.DOWN == statusChangeEvent.getPreviousStatus()) {
// log at warn level if DOWN was involved
logger.warn("Saw local status change event {}", statusChangeEvent);
} else {
logger.info("Saw local status change event {}", statusChangeEvent);
}
instanceInfoReplicator.onDemandUpdate();
}
}; if (clientConfig.shouldOnDemandUpdateStatusChange()) {
applicationInfoManager.registerStatusChangeListener(statusChangeListener);
}
//服务注册
instanceInfoReplicator.start(clientConfig.getInitialInstanceInfoReplicationIntervalSeconds());
} else {
logger.info("Not registering with Eureka server per configuration");
}
}
上述代码中有几处需要注意,这些关键点在后面的章节将继续展开:
a. 周期性更新服务列表;
b. 周期性服务续约;
c. 服务注册逻辑被放入Runnable实现类InstanceInfoReplicator之中,在新线程中执行;
SpringCloud-Eureka-服务注册是如何发起的的更多相关文章
- 将SpringCloud Eureka 服务注册与发现部署到docker
一.前言 最近在学习docker,顺便把之前学习的spring cloud 部署到Docker 中.至于什么是SpringCloud的服务注册与发现,什么是docker,我这里就不作赘述了.可以先去学 ...
- SpringCloud Eureka服务注册及发现——服务端/客户端/消费者搭建
Eureka 是 Netflix 出品的用于实现服务注册和发现的工具. Spring Cloud 集成了 Eureka,并提供了开箱即用的支持.其中, Eureka 又可细分为 Eureka Serv ...
- springcloud(第三篇)springcloud eureka 服务注册与发现 *****
http://blog.csdn.net/liaokailin/article/details/51314001 ******************************************* ...
- SpringCloud——Eureka服务注册和发现
一.SpringCloud和Dubbo SpringCloud整合了一套较为完整的微服务解决方案框架,而Dubbo只是解决了微服务的几个方面的问题. content Dubbo SpringCloud ...
- SpringCloud Eureka 服务注册与服务发现
一.Eureka简介 spring Cloud Netflix技术栈中,Eureka作为服务注册中心对整个微服务架构起着最核心的整合作用.有了服务发现与注册,你就不需要整天改服务调用的配置文件了,你只 ...
- SpringCloud(3)---Eureka服务注册与发现
Eureka服务注册与发现 一.Eureka概述 1.Eureka特点 (1) Eureka是一个基于REST的服务,用于定位服务,以实现云端中间层服务发现和故障转移. (2) Eureka 主管服务 ...
- java框架之SpringCloud(3)-Eureka服务注册与发现
在上一章节完成了一个简单的微服务案例,下面就通过在这个案例的基础上集成 Eureka 来学习 Eureka. 介绍 概述 Eureka 是 Netflix 的一个子模块,也是核心模块之一.Eureka ...
- SpringCloud之服务注册-eureka
类似于DUBBO 的zookeeper, SpringCloud本身提供一套服务注册中心--eureka 与zookeeper的区别在于 1:zookeeper本身就是一个应用,安装即可用:eurek ...
- 微服务框架SpringCloud(Dalston版)学习 (一):Eureka服务注册与发现
eureka-server eureka服务端,提供服务的注册与发现,类似于zookeeper 新建spring-boot工程,pom依赖: <dependency> <groupI ...
- SpringCloud 进阶之Eureka(服务注册和发现)
1. Eureka 服务注册与发现 Eureka 是一个基于REST的服务,用于服务的的注册与发现; Eureka采用C-S的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册 ...
随机推荐
- Debug to add expression
Debug expression
- 用C语言编程乘法口诀表
首先是全部,代码如下: #include<stdio.h> void main() { int i,j; ;i<=;i++) { ;j<=;j++) printf(" ...
- UI自动化前置代码
一.前置代码: #导入包selenium from selenium import webdriverimport time#创键一个火狐对象driver=webdriver.Firefox()#防问 ...
- python 生成多维数组
在刷题时用到了数组,因为不提供三方库所以不能使用Numpy.想如何通过python列表模拟数组. 第一种方法 """ 生成n*m的初始值为0的矩阵 "" ...
- leetcode_1293. Shortest Path in a Grid with Obstacles Elimination_[dp动态规划]
题目链接 Given a m * n grid, where each cell is either 0 (empty) or 1 (obstacle). In one step, you can m ...
- codeforces_D. Treasure Hunting_[DP+Binary Search]
http://codeforces.com/contest/1201/problem/D 题意:n行m列的矩阵中,有k个targets,从[1, 1]出发,每次只能向上下左右四个方向移动一步,且只有在 ...
- 基于MyBatis实现Dao理论
基于MyBatis实现Dao理论 推荐使用xml提供sql 实现接口推荐使用Mapper自动实现DAO接口,让我们更关注sql书写本身
- 31 October
https://www.cnblogs.com/RabbitHu/p/51nod1353.html 树形 DP 求所有联通块 \(\ge K\) 的方案数. 切断:\(\forall i\in\lef ...
- 夯实Java基础系列7:Java 代码块和执行顺序
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- Uva 12563 Jin Ge Jin Qu hao(01背包)
题意: 假定你在唱KTV,还剩下t秒时间.你决定接下来唱你最喜爱的n首歌(不包含劲歌金曲)中的一些歌曲.在时间结束之前再唱一个劲歌金曲.使得唱的歌的总曲目尽量多以及时间总长度. 输入保证所有n+1曲子 ...