所有文章

https://www.cnblogs.com/lay2017/p/11908715.html

正文

上一篇文章,我们稍微了解了一下eureka客户端是如何自动配置的,配置了哪些东西。在自动配置的时候会产生一个负责自动注册的Bean,也就是

@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);
}

所以,我们打开EurekaAutoServiceRegistration看看

public class EurekaAutoServiceRegistration implements AutoServiceRegistration, SmartLifecycle, Ordered, SmartApplicationListener {

    private ApplicationContext context;

    private EurekaServiceRegistry serviceRegistry;

    private EurekaRegistration registration;

    public EurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry serviceRegistry, EurekaRegistration registration) {
this.context = context;
this.serviceRegistry = serviceRegistry;
this.registration = registration;
} @Override
public void start() {
// ... if (!this.running.get() && this.registration.getNonSecurePort() > 0) { // 调用注册
this.serviceRegistry.register(this.registration); this.context.publishEvent(new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig())); this.running.set(true);
}
} }

注册任务被委托给了serviceRegistry来做,跟进register方法

@Override
public void register(EurekaRegistration reg) {
maybeInitializeClient(reg); // ... reg.getApplicationInfoManager().setInstanceStatus(reg.getInstanceConfig().getInitialStatus()); reg.getHealthCheckHandler().ifAvailable(healthCheckHandler -> reg.getEurekaClient().registerHealthCheck(healthCheckHandler));
}

调用了eurekaClient原始的registerhealthCheck方法,跟进它

@Override
public void registerHealthCheck(HealthCheckHandler healthCheckHandler) {
if (instanceInfo == null) {
logger.error("Cannot register a healthcheck handler when instance info is null!");
}
if (healthCheckHandler != null) {
// 注册心跳检查处理器
this.healthCheckHandlerRef.set(healthCheckHandler); // schedule an onDemand update of the instanceInfo when a new healthcheck handler is registered
if (instanceInfoReplicator != null) {
instanceInfoReplicator.onDemandUpdate();
}
}
}

心跳检查处理器被设置为了成员变量,执行的核心逻辑被托付给了onDemandUpdate方法,跟进它

public boolean onDemandUpdate() {
if (rateLimiter.acquire(burstSize, allowedRatePerMinute)) {
if (!scheduler.isShutdown()) {
scheduler.submit(new Runnable() {
@Override
public void run() {
// ...

InstanceInfoReplicator.this
.run();
}
});
return true;
} else {
// ...
}
} else {
// ...
}
}

单线程异步执行了当前类的run方法,进入run方法

public void run() {
try {
// 刷新实例信息
discoveryClient.refreshInstanceInfo(); Long dirtyTimestamp = instanceInfo.isDirtyWithTime();
if (dirtyTimestamp != null) {
// 注册
discoveryClient.register();
instanceInfo.unsetIsDirty(dirtyTimestamp);
}
} catch (Throwable t) {
// ...
} finally {
// 下一次延迟执行
Future next = scheduler.schedule(this, replicationIntervalSeconds, TimeUnit.SECONDS);
scheduledPeriodicRef.set(next);

}
}

run方法每次执行都会刷新实例信息,然后调用register注册新的实例信息,最后发出下一次执行的延迟任务

跟进register方法

boolean register() throws Throwable {
logger.info(PREFIX + "{}: registering service...", appPathIdentifier);
EurekaHttpResponse<Void> httpResponse;
try {
// 发出远程请求
httpResponse = eurekaTransport.registrationClient.register(instanceInfo);
} catch (Exception e) { } return httpResponse.getStatusCode() == Status.NO_CONTENT.getStatusCode();
}

继续跟进register方法,发出了http请求,这里以jersey为例

@Override
public EurekaHttpResponse<Void> register(InstanceInfo info) {
String urlPath = "apps/" + info.getAppName();
ClientResponse response = null;
try {
Builder resourceBuilder = jerseyClient.resource(serviceUrl).path(urlPath).getRequestBuilder();
addExtraHeaders(resourceBuilder);
response = resourceBuilder
.header("Accept-Encoding", "gzip")
.type(MediaType.APPLICATION_JSON_TYPE)
.accept(MediaType.APPLICATION_JSON)
// 发出http请求
.post(ClientResponse.class, info);
return anEurekaHttpResponse(response.getStatus()).headers(headersOf(response)).build();
} finally {
if (logger.isDebugEnabled()) {
logger.debug("Jersey HTTP POST {}/{} with instance {}; statusCode={}", serviceUrl, urlPath, info.getId(),
response == null ? "N/A" : response.getStatus());
}
if (response != null) {
response.close();
}
}
}

http请求将进入eureka服务端,注册实例信息有兴趣可以看看eureka服务端注册服务这篇。

总结

eureka客户端自动注册服务主要是将自动配置的时候拿到的实例信息通过http请求发送给eureka服务端,默认30秒会执行一次。

六、eureka客户端自动注册服务的更多相关文章

  1. 五、eureka客户端自动配置

    所有文章 https://www.cnblogs.com/lay2017/p/11908715.html 正文 前面的几篇文章中,我们从eureka Server端的角度看了看eureka的几个核心要 ...

  2. 自动注册服务NET Core扩展IServiceCollection

    NET Core扩展IServiceCollection自动注册服务 前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中, ...

  3. 自学Zabbix9.3 zabbix客户端自动注册

    自学Zabbix9.3 zabbix客户端自动注册 1. 概述 网络自动发现配置,只要就是zabbix server去扫描一个网段,把在线的主机添加到Host列表中.但是Active agent是主动 ...

  4. .NET Core扩展IServiceCollection自动注册服务

    前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中,通过IServiceCollection接口进行注入即可,其它的无需关 ...

  5. Eureka客户端无法连接服务注册中心

    转载自:https://my.oschina.net/kousm/blog/2249003 服务端 application.yml配置 spring: application: name: eurek ...

  6. 如何在Windows Server 2008 R2 SP1安装Redis-x64-3.2.100,并且自动注册服务

    1.官网:http://redis.io/ 2.下载地址:https://github.com/MSOpenTech/redis/releases 3.最新的安装包: 4.点击msi文件开始安装. 5 ...

  7. zabbix客户端自动注册

    1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中.我们本篇内容与上篇相反,这次是Active age ...

  8. (62)zabbix客户端自动注册

    1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中. 我们本篇内容与上篇相反,这次是Active ag ...

  9. 在 CentOS6 上安装 Zabbix3.0 Agent 并开启客户端自动注册

    #!/bin/bash # # .配置yum源 # cat /etc/redhat-release |grep -i centos |grep '6.[[:digit:]]' &>/de ...

随机推荐

  1. YII2 composer update 报错解决一例-requires bower-asset/jquery 2.2

    ➜  yii-advanced composer update Loading composer repositories with package information Updating depe ...

  2. leetcode 290. Word Pattern 、lintcode 829. Word Pattern II

    290. Word Pattern istringstream 是将字符串变成字符串迭代器一样,将字符串流在依次拿出,比较好的是,它不会将空格作为流,这样就实现了字符串的空格切割. C++引入了ost ...

  3. Vue中创建单文件组件 注册组件 以及组件的使用

    <template> <div id="app"> <v-home></v-home> <hr > <br> ...

  4. 【Git】 Git安装及配置

    Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.而国外的GitHub和国内的Coding都是项目的托管平台. 本例使用环境:Linux环境(CentOS 7.4 ...

  5. k8s-基础环境配置(六)

    hostname配置1)修改主机名hostnamectl set-hostname xxx2)加入主机映射vim /etc/hosts……关闭selinuxsed -i '/^SELINUX/s/=. ...

  6. Oracle索引 详解

    作者:Dave 一.索引介绍 1.1 索引的创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name> ON <sc ...

  7. springboot 整合 Froala Editor 3

    springboot项目中使用 Froala Editor 3,参考官网文档:https://www.froala.com/wysiwyg-editor/docs/overview 下载文件后,引入c ...

  8. didMoveToSuperview方法认识和使用

    由来: 今天给项目添加新功能——点击弹出阳历,阴历日期选择. 弹出日期选择是弹出的控制器,里面的日期选择控件是封装的View,View使用Xib画的, 遇到的问题是:控制器传数据给View,在awak ...

  9. shell脚本双引号、大括号、if语句注意事项

    1.双引号的问题 变量用双引号括起来的意义 如果变量不用双引号括起来,比如echo $a,那么隐含的意义就是,把$a变量的字符串,按照空格.制表符.换行符等符号来分割开.然后把这些分割后的每一项再按 ...

  10. python signal模块

    signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时发出SIGALRM等.要注意,signal包主要是针对UNIX平台(比如Linux, MAC ...