本文已参与「新人创作礼」活动,一起开启掘金创作之路。
服务端实例构造(注册相关)
// 第四步,注册相关
// 可以发现集群中节点的服务实例注册表
PeerAwareInstanceRegistry registry;
if (isAws(applicationInfoManager.getInfo())) { // 判断 实例信息 是不是 aws类型实例
// 如果是 aws类型实例
registry = new AwsInstanceRegistry(eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);
awsBinder = new AwsBinderDelegate(eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), registry, applicationInfoManager);
awsBinder.start();
} else {
// 如果不是 aws类型实例
// 获取 PeerAwareInstanceRegistry 注册表
// 服务配置信息、客户端配置信息、服务编码组件、客户端组件
registry = new PeerAwareInstanceRegistryImpl(eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);
}
// 根据 注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(registry, eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), serverCodecs, applicationInfoManager);
// 获取 eureka服务上下文
serverContext = new DefaultEurekaServerContext(eurekaServerConfig, serverCodecs, registry
, peerEurekaNodes, applicationInfoManager);
// 构建 EurekaServerContextHolder 持有 EurekaServerContext serverContext
EurekaServerContextHolder.initialize(serverContext);
// EurekaServerContext serverContext eureka服务上下文初始化
serverContext.initialize();
logger.info("Initialized server context");
// 从相邻的一个eureka server节点拷贝注册表的信息,如果拷贝失败,就找下一个
// Copy registry from neighboring eureka node
int registryCount = registry.syncUp();
registry.openForTraffic(applicationInfoManager, registryCount);
// 注册所有跟踪监控统计数据
// Register all monitoring statistics.
EurekaMonitors.registerAllStats();
构造 PeerAwareInstanceRegistry
Peer:多个同样的东西组成的一个集群。
Peers:peer就是集群中的一个实例
PeerAware:可以识别eureka server集群的
InstanceRegistry:服务实例注册表。存放所有的注册到这个eureka server上来的服务实例。
PeerAwareInstanceRegistry:可以感知eureka server集群的服务实例注册表,eureka client(作为服务实例)过来注册的注册表,而且这个注册表是可以感知
到eureka server集群的。
Aware:假如有一个eureka server集群的话,这里包含了其他的eureka server中的服务实例注册表的信息的。
包含:服务配置信息、客户端配置信息、服务编码组件、客户端组件
// 服务配置信息、客户端配置信息、服务编码组件、客户端组件
registry = new PeerAwareInstanceRegistryImpl(eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), serverCodecs, eurekaClient);
构造PeerEurekaNodes
PeerEurekaNodes:eureka-server集群。
包含:注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
// 根据 注册表、eureka-server配置信息、eureka-client 配置信息、服务编码组件、应用信息管理器等获取 Eureka单个服务节点 实例
PeerEurekaNodes peerEurekaNodes = getPeerEurekaNodes(registry, eurekaServerConfig,
eurekaClient.getEurekaClientConfig(), serverCodecs, applicationInfoManager);
PeerEurekaNode:表示指向该信息的对等节点应该从这个节点共享。
处理所有更新操作的复制同步,例如注册、更新、取消、过期和状态更改到它所代表的eureka节点。
/**
* The <code>PeerEurekaNode</code> represents a peer node to which information
* should be shared from this node.
*
* <p>
* This class handles replicating all update operations like
* <em>Register,Renew,Cancel,Expiration and Status Changes</em> to the eureka
* node it represents.
* <p>
*
* @author Karthik Ranganathan, Greg Kim
*
*/
public class PeerEurekaNode {
}
构造EurekaServerContext
EurekaServerContext:当前eureka server的服务器上下文,包含服务器需要的所有的数据。
EurekaServerContextHolder.initialize(serverContext);
将EurekaServerContext放在holder中,要使用EurekaServerContext,直接从这个holder中获取。
EurekaServerContext.initialize()
@PostConstruct
@Override
public void initialize() throws Exception {
logger.info("Initializing ...");
// 启动 eureka-server 集群
peerEurekaNodes.start();
// 基于eureka server集群的信息,来初始化注册表
registry.init(peerEurekaNodes);
logger.info("Initialized");
}
peerEurekaNodes.start();
启动eureka server集群,更新eureka server集群的信息,让当前的eureka server感知到所有的其他的eureka server。
定时调度任务,更新eureka server集群的信息。
/**
* 启动eureka server集群
*/
public void start() {
taskExecutor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r, "Eureka-PeerNodesUpdater");
thread.setDaemon(true);
return thread;
}
});
try {
// 更新 eureka-server 集群信息,让当前的eureka server感知到所有的其他的eureka server
updatePeerEurekaNodes(resolvePeerUrls());
// 定时更新eureka server集群的信息的任务
Runnable peersUpdateTask = new Runnable() {
@Override
public void run() {
try {
updatePeerEurekaNodes(resolvePeerUrls());
} catch (Throwable e) {
logger.error("Cannot update the replica Nodes", e);
}
}
};
// 定时更新eureka server集群的信息。
taskExecutor.scheduleWithFixedDelay(peersUpdateTask,
serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
serverConfig.getPeerEurekaNodesUpdateIntervalMs(), TimeUnit.MILLISECONDS);
} catch (Exception e) {
throw new IllegalStateException(e);
}
for (PeerEurekaNode node : peerEurekaNodes) {
logger.info("Replica node URL: " + node.getServiceUrl());
}
}
registry.init(peerEurekaNodes);
- 基于eureka server集群的信息,初始化注册表
- 将eureka server集群中所有的eureka server的注册表信息都抓取过来,合并到本地的注册表里去,
- 交换eureka server集群之间的注册表信息,保持同步
@Override
public void init(PeerEurekaNodes peerEurekaNodes) throws Exception {
this.numberOfReplicationsLastMin.start();
this.peerEurekaNodes = peerEurekaNodes;
initializedResponseCache();
scheduleRenewalThresholdUpdateTask();
initRemoteRegionRegistry();
try {
Monitors.registerObject(this);
} catch (Throwable e) {
logger.warn("Cannot register the JMX monitor for the InstanceRegistry :", e);
}
}
registry.syncUp();
从相邻的一个eureka server节点拷贝注册表的信息,如果拷贝失败,就找下一个。
/**
* Populates the registry information from a peer eureka node. This
* operation fails over to other nodes until the list is exhausted if the
* communication fails.
*/
@Override
public int syncUp() {
// Copy entire entry from neighboring DS node
int count = 0;
for (int i = 0; ((i < serverConfig.getRegistrySyncRetries()) && (count == 0)); i++) {
if (i > 0) {
try {
Thread.sleep(serverConfig.getRegistrySyncRetryWaitMs());
} catch (InterruptedException e) {
logger.warn("Interrupted during registry transfer..");
break;
}
}
Applications apps = eurekaClient.getApplications();
for (Application app : apps.getRegisteredApplications()) {
for (InstanceInfo instance : app.getInstances()) {
try {
if (isRegisterable(instance)) {
register(instance, instance.getLeaseInfo().getDurationInSecs(), true);
count++;
}
} catch (Throwable t) {
logger.error("During DS init copy", t);
}
}
}
}
return count;
}
EurekaMonitors.registerAllStats();
注册所有跟踪监控统计数据
// Register all monitoring statistics.
EurekaMonitors.registerAllStats();