Eureka架构设计解析
- 什么是分布式注册中心?有何作用?去掉分布式配置中心会产生什么样的后果?
分布式注册中心就是提供一个管理服务之间通信的一个平台。它的作用就是协调服务与服务之间通信的简化。若去掉分布式配置中心,服务与服务之间通信就需要知道具体的IP+端口+服务名称,这样的话给服务管理上无疑是带来了管理的成本。一旦被调用的服务IP,端口更换的话,调用端就必须同步更换(例如旧服务下线,新服务上线,无法做到及时更新)。
- 一个分布式注册中心应该具备哪些功能组件?
register(注册),renewal(续约),unRegister(下线),replication(集群同步),集群选举(CP模式专属)
- Eureka架构设计解析
Client代码解析
- Springboot starter启动
Spring-cloud-netflix-eureka-client中META-INF/spring.factories配置了
EurekaClientAutoConfiguration(springboot starter组件都是利用这种模式启动第三方插件)
- 通过@Bean注解初始化客户端基本配置信息
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config)
- 创建EurekaClient
EurekaClientAutoConfiguration中配置RefreshableEurekaClientConfiguration初始化bean:EurekaClient
- CloudEurekaClient父类为DiscoveryClient,执行构造器时初始化多个线程池(scheduler,heartbeatExecutor,heartbeatExecutor)
DiscoverClient构造器中初始化scheduler(nameFormat: DiscoveryClient-%d)
,heartbeatExecutor(nameFormat: DiscoveryClient-HeartbeatExecutor-%d),cacheRefreshExecutor(nameFormat: DiscoveryClient-CacheRefreshExecutor-%d)三个线程池
- fetchRegistry(获取注册中心的服务信息)
- initScheduledTasks(初始化计划任务:注册,心跳),并设置状态变化监听
- 更改初始化状态
- 注册scheduler进行submit,InstanceInfoReplicator.this.run(); 最终开始register
- 根据之前初始化的instanceInfo对eureka Server进行注册
- 利用jer进行注册(jer是一种轻量级RESTFul风格的Web Services框架)
- 续约,按照heartbeatExecutor中HeartbeatThread的run
- 服务下线
Client代码解析总结
- 首先是根据SpringBoot starter启动配置。
- 初始化客户端注册信息(instanceInfo)
- 初始化多个线程池,注册线程池,心跳续约线程池,缓存刷新线程池
- 获取注册中心的其他注册服务信息
- 初始化scheduleTask进行注册,续约线程启动
- 服务下线
Server代码解析
- SpringBoot starter启动
SpringBoot starter整合其他框架一般都是从spring.factories中的开启自动配置开始。一般我们要想分析源码就可以从这里入手
- 注入EurekaServer初始化配置
- 利用Import导入EurekaServer初始化配置,因为
EurekaServerInitializerConfiguration实现了Lifecycle接口,Lifecycle是容器的生命周期接口,一旦容器初始化就会执行。所以会启动start方法进行EurekaServerBootstrap的容器初始化。
- 初始化EurekaServer配置
- initEurekaServerContext中同步其他集群节点上的node
- 开启心跳续约轮询,剔除过期服务
- 心跳续约清除具体详情,使用的是读写锁+同步锁
- 初始化EurekaServer容器
DefaultEurekaServerContext的bean初始化,initialize上有@PostConstruct(java提供)注解,表示bean初始化后执行方法。
peerEurekaNodes启动,创建task线程池,用于同步其他集群节点(注意,在同步的时候)
- 在PeerEurekaNode创建batchingDispatcher,目的是为了在服务接受到注册请求时,调用该dispatcher将register请求放入链表中。等待acceptorExecutor进行轮询同步其他节点。
- 在这块调用process去submitBatchUpdates,利用jerseyApacheClient去,并且批量更新失败还会进行reprocess,这块设计的特别复杂。
- 注册
- 客户端发送注册请求到服务端入口
ApplicationResource. addInstance
- 读写锁进行注册,如果registry中没有,就新建一个map放入其中
Server代码总结
- 利用SpringBoot starter启动并初始化
- 初始化时开启心跳续约,剔除Timer
- 创建peerEurekaNodes,创建task线程池,创建时并不做其他EurekaServer节点的连接,只在接受到register消息时,才利用process去同步其他节点。
- 并且在做同步的时候使用的是链表的生产者与消费者模型,process将task放入链表中,task的线程死循环轮询读取消息。(若是同步失败的话,还会进行reprocess,也是以同样的形式)
- 接受注册请求,将消息注册到容器中,然后去同步其他集群节点。
- 下线(下线就不做代码解析了,理论差不多,无非就是清除,再同步其他节点而已)
- 集群选举(Eureka是相互注册同步,没有选举模式)