六、eureka客户端自动注册服务
所有文章
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客户端自动注册服务的更多相关文章
- 五、eureka客户端自动配置
所有文章 https://www.cnblogs.com/lay2017/p/11908715.html 正文 前面的几篇文章中,我们从eureka Server端的角度看了看eureka的几个核心要 ...
- 自动注册服务NET Core扩展IServiceCollection
NET Core扩展IServiceCollection自动注册服务 前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中, ...
- 自学Zabbix9.3 zabbix客户端自动注册
自学Zabbix9.3 zabbix客户端自动注册 1. 概述 网络自动发现配置,只要就是zabbix server去扫描一个网段,把在线的主机添加到Host列表中.但是Active agent是主动 ...
- .NET Core扩展IServiceCollection自动注册服务
前言 在ASP.NET Core中使用依赖注入中使用很简单,只需在Startup类的ConfigureServices()方法中,通过IServiceCollection接口进行注入即可,其它的无需关 ...
- Eureka客户端无法连接服务注册中心
转载自:https://my.oschina.net/kousm/blog/2249003 服务端 application.yml配置 spring: application: name: eurek ...
- 如何在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 ...
- zabbix客户端自动注册
1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中.我们本篇内容与上篇相反,这次是Active age ...
- (62)zabbix客户端自动注册
1. 概述 上一篇内容<zabbix自动发现配置>,大概内容是zabbix server去扫描一个网段,把在线的主机添加到Host列表中. 我们本篇内容与上篇相反,这次是Active ag ...
- 在 CentOS6 上安装 Zabbix3.0 Agent 并开启客户端自动注册
#!/bin/bash # # .配置yum源 # cat /etc/redhat-release |grep -i centos |grep '6.[[:digit:]]' &>/de ...
随机推荐
- 实战一:LoadRunner性能测试利器
转自:https://blog.csdn.net/weixin_42350428/article/details/82106603 企业的网络应用环境都必须支持大量用户,网络体系架构中含各类应用环境且 ...
- Python3实战——爬虫入门
一.安装库 使用conda安装: conda install requests 如果出现解析环境问题,需要激活conda环境: https://www.cnblogs.com/jdemarryme/p ...
- Qt编写气体安全管理系统21-探测器管理
一.前言 探测器在整个系统中是最核心的关键的硬件,终端节点硬件,安装有探测芯片装置,负责探测前端对应气体浓度,并记录值,等待控制器轮训数据回复,控制器信息表也是字段最多的,要存储位号.控制器名称.探测 ...
- php程序无法记录log情况下可尝试下面方法记录log
error_reporting(E_ERROR | E_PARSE); function shutdownCallback(){ $arrError = error_get_last(); // ...
- 使用JSQLParser解析SQL中涉及到的表
首先添加Maven依赖: <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId& ...
- AI - H2O - 第一个示例
1 - Iris数据集 Iris数据集是常用的机器学习分类实验数据集,特点是数据量很小,可以快速学习. 数据集包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性. Sepal.Leng ...
- 【Luogu P1345】[USACO5.4]奶牛的电信Telecowmunication
Luogu P1345 很容易发现这题要求的是网络流中的最小割. 关于最小割,我们有最大流最小割定理:最小割的容量一定等于最大流的流量 但是这个定理是用于求最小割边,而题目要求我们求的是最小割点. 那 ...
- PHP实现单点登录最简单的方法
PHP实现单点登录最简单的方法 用户在A登录 存入登录状态 登录B站(A的识别要传入B) 获取A的登录状态
- Image Perimeters
Description 给出一张由"x"和"."组成的矩阵.每个"x"可以向上下左右及两个斜对角进行连通,请问由某个点开始的"x& ...
- QT qml TreeView展示数据结构于界面
Class QAbstractItemModel: 使用QML的TreeView类来展示树状的结构,对应的是QT的Model/View模型.这个model是一个数据模型,要为TreeView提供一个 ...