【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?
前言
在源码分析三、四都有提及到EurekaClient启动的一些过程。因为EurekaServer在集群模式下 自己本身就是一个client,所以之前初始化eurekaServerContext就有涉及到eurekaClient的初始化。
我们也看了EurekaClient(DiscoveryClient)初始化的过程,繁杂的启动过程让人眼花缭乱,这篇文章就专门来唠唠 里面经历的一些艰难险阻。这也会是后面client注册的一个前置文章。
如若转载 请标明来源:一枝花算不算浪漫
从ExampleEurekaClient开始说起
在第一讲我们就说过,eureka项目有一个examples模块的,现在看一下其中的EurekaClientExample对象:
public class ExampleEurekaClient {
private static ApplicationInfoManager applicationInfoManager;
private static EurekaClient eurekaClient;
private static synchronized ApplicationInfoManager initializeApplicationInfoManager(EurekaInstanceConfig instanceConfig) {
if (applicationInfoManager == null) {
InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get();
applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo);
}
return applicationInfoManager;
}
private static synchronized EurekaClient initializeEurekaClient(ApplicationInfoManager applicationInfoManager, EurekaClientConfig clientConfig) {
if (eurekaClient == null) {
eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);
}
return eurekaClient;
}
public void sendRequestToServiceUsingEureka(EurekaClient eurekaClient) {
// initialize the client
// this is the vip address for the example service to talk to as defined in conf/sample-eureka-service.properties
String vipAddress = "sampleservice.mydomain.net";
InstanceInfo nextServerInfo = null;
try {
nextServerInfo = eurekaClient.getNextServerFromEureka(vipAddress, false);
} catch (Exception e) {
System.err.println("Cannot get an instance of example service to talk to from eureka");
System.exit(-1);
}
System.out.println("Found an instance of example service to talk to from eureka: "
+ nextServerInfo.getVIPAddress() + ":" + nextServerInfo.getPort());
System.out.println("healthCheckUrl: " + nextServerInfo.getHealthCheckUrl());
System.out.println("override: " + nextServerInfo.getOverriddenStatus());
Socket s = new Socket();
int serverPort = nextServerInfo.getPort();
try {
s.connect(new InetSocketAddress(nextServerInfo.getHostName(), serverPort));
} catch (IOException e) {
System.err.println("Could not connect to the server :"
+ nextServerInfo.getHostName() + " at port " + serverPort);
} catch (Exception e) {
System.err.println("Could not connect to the server :"
+ nextServerInfo.getHostName() + " at port " + serverPort + "due to Exception " + e);
}
try {
String request = "FOO " + new Date();
System.out.println("Connected to server. Sending a sample request: " + request);
PrintStream out = new PrintStream(s.getOutputStream());
out.println(request);
System.out.println("Waiting for server response..");
BufferedReader rd = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = rd.readLine();
if (str != null) {
System.out.println("Received response from server: " + str);
System.out.println("Exiting the client. Demo over..");
}
rd.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
injectEurekaConfiguration();
ExampleEurekaClient sampleClient = new ExampleEurekaClient();
// MyDataCenterInstanceConfig 就是加载eureka-client.properties配置信息,形成一个服务实例的配置EurekaInstanceConfig
// 基于EurekaClient配置,构造了一个服务实例(InstanceInfo)
// 基于eureka client配置和服务实例,构造了一个服务实例管理器(ApplicationInfoManager)
// 读取eureka-client.properties配置文件,形成了一个eureka client的配置,接口对外提供eureka client的配置项的读取
// 基于eureka client的配置,和服务实例管理器,来构造了一个EurekaClient(DiscoveryClient
// ),保存了一些配置,处理服务的注册和注册表的抓取,启动了几个线程池,启动了网络通信组件,启动了一些调度任务,注册了监控项
ApplicationInfoManager applicationInfoManager = initializeApplicationInfoManager(new MyDataCenterInstanceConfig());
EurekaClient client = initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());
// use the client
sampleClient.sendRequestToServiceUsingEureka(client);
// shutdown the client
eurekaClient.shutdown();
}
/**
* This will be read by server internal discovery client. We need to salience it.
*/
private static void injectEurekaConfiguration() throws UnknownHostException {
String myHostName = InetAddress.getLocalHost().getHostName();
String myServiceUrl = "http://" + myHostName + ":8080/v2/";
System.setProperty("eureka.region", "default");
System.setProperty("eureka.name", "eureka");
System.setProperty("eureka.vipAddress", "eureka.mydomain.net");
System.setProperty("eureka.port", "8080");
System.setProperty("eureka.preferSameZone", "false");
System.setProperty("eureka.shouldUseDns", "false");
System.setProperty("eureka.shouldFetchRegistry", "true");
System.setProperty("eureka.serviceUrl.defaultZone", myServiceUrl);
System.setProperty("eureka.serviceUrl.default.defaultZone", myServiceUrl);
System.setProperty("eureka.awsAccessId", "fake_aws_access_id");
System.setProperty("eureka.awsSecretKey", "fake_aws_secret_key");
System.setProperty("eureka.numberRegistrySyncRetries", "0");
}
}
这里我们从main函数开始看起:
- 注入eureka配置信息:
injectEurekaConfiguration(); - 读取eureka-client.properties配置文件,形成一个服务器实例的配置,基于接口对外提供实例的配置项读取
这里就是涉及到我么你之前讲解的DynamicPropertyFactory和ConfigurationManager,这里可以查看new MyDataCenterInstanceConfig()然后一步步往后跟。 - 基于服务实例的配置,构造了一个服务实例(InstanceInfo)。
initializeApplicationInfoManager中会构建InstanceInfo信息 - 基于服务实例的配置和服务实例,初始化服务实例管理器(ApplicationInfoManager)
- 基于eureka client配置,和服务实例管理器,来构造了一个EurekaClient(DiscoveryClient),保存了一些配置,处理服务的注册和注册表的抓取,启动了几个线程池,启动了网络通信组件,启动了一些调度任务,注册了监控项
具体可查看EurekaClient client = initializeEurekaClient(applicationInfoManager, new DefaultEurekaClientConfig());
流程图

申明
本文章首发自本人博客:https://www.cnblogs.com/wang-meng 和公众号:壹枝花算不算浪漫,如若转载请标明来源!
感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫

【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?的更多相关文章
- 【一起学源码-微服务】Eureka+Ribbon+Feign阶段性总结
前言 想说的话 这里已经梳理完Eureka.Ribbon.Feign三大组件的基本原理了,今天做一个总结,里面会有一个比较详细的调用关系流程图. 说明 原创不易,如若转载 请标明来源! 博客地址:一枝 ...
- 【一起学源码-微服务】Ribbon源码五:Ribbon源码解读汇总篇~
前言 想说的话 [一起学源码-微服务-Ribbon]专栏到这里就已经全部结束了,共更新四篇文章. Ribbon比较小巧,这里是直接 读的spring cloud 内嵌封装的版本,里面的各种config ...
- 【一起学源码-微服务】Ribbon 源码三:Ribbon与Eureka整合原理分析
前言 前情回顾 上一篇讲了Ribbon的初始化过程,从LoadBalancerAutoConfiguration 到RibbonAutoConfiguration 再到RibbonClientConf ...
- 【一起学源码-微服务】Feign 源码一:源码初探,通过Demo Debug Feign源码
前言 前情回顾 上一讲深入的讲解了Ribbon的初始化过程及Ribbon与Eureka的整合代码,与Eureka整合的类就是DiscoveryEnableNIWSServerList,同时在Dynam ...
- 【一起学源码-微服务】Ribbon 源码一:Ribbon概念理解及Demo调试
前言 前情回顾 前面文章已经梳理清楚了Eureka相关的概念及源码,接下来开始研究下Ribbon的实现原理. 我们都知道Ribbon在spring cloud中担当负载均衡的角色, 当两个Eureka ...
- 【一起学源码-微服务】Ribbon 源码二:通过Debug找出Ribbon初始化流程及ILoadBalancer原理分析
前言 前情回顾 上一讲讲了Ribbon的基础知识,通过一个简单的demo看了下Ribbon的负载均衡,我们在RestTemplate上加了@LoadBalanced注解后,就能够自动的负载均衡了. 本 ...
- 【一起学源码-微服务】Ribbon 源码四:进一步探究Ribbon的IRule和IPing
前言 前情回顾 上一讲深入的讲解了Ribbon的初始化过程及Ribbon与Eureka的整合代码,与Eureka整合的类就是DiscoveryEnableNIWSServerList,同时在Dynam ...
- 【一起学源码-微服务】Feign 源码三:Feign结合Ribbon实现负载均衡的原理分析
前言 前情回顾 上一讲我们已经知道了Feign的工作原理其实是在项目启动的时候,通过JDK动态代理为每个FeignClinent生成一个动态代理. 动态代理的数据结构是:ReflectiveFeign ...
- 【一起学源码-微服务】Feign 源码二:Feign动态代理构造过程
前言 前情回顾 上一讲主要看了@EnableFeignClients中的registerBeanDefinitions()方法,这里面主要是 将EnableFeignClients注解对应的配置属性注 ...
随机推荐
- Libev源码分析08:Libev中的信号监视器
Libev中的信号监视器,用于监控信号的发生,因信号是异步的,所以Libev的处理方式是尽量的将异步信号同步化.异步信号的同步化方法主要有:signalfd.eventfd.pipe.sigwaiti ...
- MySQL数据库优化(五)——MySQL查询优化
http://blog.csdn.net/daybreak1209/article/details/51638187 一.mysql查询类型(默认查询出所有数据列)1.内连接 默认多表关联 ...
- D-query SPOJ - DQUERY 主席树查询区间内不同数出现的次数
我们不以权值建立主席树,而是区间端点作为值建立线段树,一个个插入a[i],我们发现这个数之前是存在的,就需要在上个版本的主席树上减去原来的位置,并加上现在的位置,这样我们在i版本的主席树,维护1-r中 ...
- H3C ICMP
- SuperSocket 服务器管理器客户端
SuperSocket 服务器管理器当前有两种类型的客户端, Silverlight客户端和WPF客户端.这两种客户端的代码都在源代码中的"Management"目录,你可以自行编 ...
- Java反射机制(四):动态代理
一.静态代理 在开始去学习反射实现的动态代理前,我们先需要了解代理设计模式,那何为代理呢? 代理模式: 为其他对象提供一种代理,以控制对这个对象的访问. 先看一张代理模式的结构图: 简单的理解代理设计 ...
- 5 分钟入门 Google 最强NLP模型:BERT
BERT (Bidirectional Encoder Representations from Transformers) 10月11日,Google AI Language 发布了论文 BERT: ...
- 洛谷P2672 推销员 题解 贪心
题目链接:https://www.luogu.org/problem/P2672 这道题目是贪心,贪心的思想是: 选择 \(m\) 户人家的最大疲劳值应该是以下两种方案中的较大值: 方案一:选择 \( ...
- tensorflow -gpu安装,史上最新最简单的途径(不用自己装cuda,cdnn)
tensorflow -gpu安装首先,安装Anoconda1. 官网下载点我: 2.安装 点击 python 3.6 version自动下载x64版,下载好之后,然后安装. 如图,打上勾之后,一路n ...
- java List接口
Collection子接口: List是有序的集合,集合中每个元素都有对应的顺序序列.List集合可使用重复元素,可以通过索引来访问指定位置的集合元素(顺序索引从0开始),List集合默认按元素的添加 ...