前面我们了解完了eureka client的源码,我们接下来了解下server端的源码,server端主要是用于服务的发现,高可用,客户端异常如何实现自我保护机制,我们还是首先通过META-INFO下的spring.factories了解到入口类是EurekaServerAutoConfiguration,通过下图可以看到该类的结构如下
在类中实现了很多bean的初始化,下面我们看下它是如何实现高可用的。
进入到EurekaServerContext对应的bean方法中,它返回了一个默认的DefaultEurekaServerContext类,进入到该类可以立即看到它实现了一个initialize()方法,在这个方法中调用了PeerEurekaNodes类的 start()方法,这里需要说明的是因为eureka是C(最终一致性)A(可用性)P(分区容错性)理论中的AP,因此各个服务节点是平等的,没有主从节点的说法,进入到start()方法它有这样一段代码
updatePeerEurekaNodes(resolvePeerUrls());
Runnable peersUpdateTask = new Runnable() {
@Override
public void run() {
try {
updatePeerEurekaNodes(resolvePeerUrls());
} catch (Throwable e) {
.....
}
}
};
taskExecutor.scheduleWithFixedDelay(
peersUpdateTask,
serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
serverConfig.getPeerEurekaNodesUpdateIntervalMs(),
TimeUnit.MILLISECONDS
);
resolvePeerUrls()方法通过去获取eureka.client.serviceUrl的配置服务端地址列表,然后将该列表传递给updatePeerEurekaNodes()方法,我们看下updatePeerEurekaNodes()方法
Set<String> toShutdown = new HashSet<>(peerEurekaNodeUrls);
toShutdown.removeAll(newPeerUrls);
Set<String> toAdd = new HashSet<>(newPeerUrls);
toAdd.removeAll(peerEurekaNodeUrls);
if (toShutdown.isEmpty() && toAdd.isEmpty()) { // No change
return;
}
// Remove peers no long available
List<PeerEurekaNode> newNodeList = new ArrayList<>(peerEurekaNodes);
if (!toShutdown.isEmpty()) {
...
int i = 0;
while (i < newNodeList.size()) {
PeerEurekaNode eurekaNode = newNodeList.get(i);
if (toShutdown.contains(eurekaNode.getServiceUrl())) {
newNodeList.remove(i);
eurekaNode.shutDown();
} else {
i++;
}
}
}
// Add new peers
if (!toAdd.isEmpty()) {
...
for (String peerUrl : toAdd) {
newNodeList.add(createPeerEurekaNode(peerUrl));
}
}
this.peerEurekaNodes = newNodeList;
this.peerEurekaNodeUrls = new HashSet<>(newPeerUrls);
在方法中使用了toShutdown和toAdd的2个set变量,toShutdown初始化的数据是已经存在过的节点数据url地址,它把现有的节点数据删除,那么剩下的就是需要删除的节点数据了,而toAdd的初始化数据是现有的节点数据url地址,它把已经存在的节点数据删除,那么剩下的就是新增的节点数据了,接下来初始化newNodeList的节点数据,删除满足在toShutdown的set集合中url地址对应的节点,同时关闭节点相关的操作,对于新增的节点,则先通过去创建一个HttpReplicationClient对象,该对象是用于向其他服务端的注册的jersy对象,然后再创建一个PeerEurekaNode对象,然后保存到newNodeList的节点,最后给全局对象进行赋值操作,该全局对象在前面已经提到过作用。
通过以上的分析我们就明白了eureka的服务发现和服务高可用的状态的实现,接下来文章我们在分析其他的实现。