Eureka 是一种基于 REST(Representational State Transfer)的服务,以实现中间层服务器的负载平衡和故障转移。我们称这个服务为Eureka Server。Eureka 还附带了一个基于 Java 的客户端组件,即Eureka Client,这使得与服务的交互更加容易。客户端还有一个内置的负载均衡器,可以进行基本的循环负载均衡。在 Netflix,一个更复杂的负载均衡器包裹 Eureka 以提供基于流量、资源使用、错误条件等多个因素的加权负载均衡。
一、eureka架构方式
1.1、eureka支持哪些架构
由于eureka最求的是AP 可用性、分区容错性。所以eureka天然就失去了数据一致性的特征,也决定了eureka架构中不会存在主节点这个概念。eureka各个节点都是平等的,eureka属于负载均衡集群LB架构。
1.2、eureka数据特征
- eureka各个节点平等且相互为副本
- eureka在断网场景数据会出现不一致
二、eureka部署方式
官网给的eureka配置比较繁琐,但是他给的不是错的。通过读eureka源码我发现其实eureka配置可以跟简单,这种简单配置方便运维方便自己理解。官方给的配置其实是在强调eureka不应该自己注册到自己导致死循环,他源码已经屏蔽掉这种情况的发生。
2.1、最简单的eureka配置
#推荐最简单的部署方式,共计4个节点,此总部署方式会不会出现eureka自己注册自己导致死循环,不会!
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://IP1:8888/eureka/,http://IP2:8888/eureka/,http://IP3:8888/eureka/,http://IP4:8888/eureka/
instance:
prefer-ip-address: true
2.2、serviceUrl写全部节点原因
serviceUrl的作用就是当前节点获取其他节点的链接集合。
//1、eureka初始化数据节点如何同步 PeerEurekaNodes.java
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 {
//节点数据同步的时候是排除自己的
updatePeerEurekaNodes(resolvePeerUrls());
Runnable peersUpdateTask = new Runnable() {
@Override
public void run() {
try {
updatePeerEurekaNodes(resolvePeerUrls());
} catch (Throwable e) {
logger.error("Cannot update the replica Nodes", e);
}
}
};
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());
}
}
//2、eureka获取副本链接方法 副本定义:除掉自己的都是副本
protected List<String> resolvePeerUrls() {
InstanceInfo myInfo = applicationInfoManager.getInfo();
String zone = InstanceInfo.getZone(clientConfig.getAvailabilityZones(clientConfig.getRegion()), myInfo);
List<String> replicaUrls = EndpointUtils
.getDiscoveryServiceUrls(clientConfig, zone, new EndpointUtils.InstanceInfoBasedUrlRandomizer(myInfo));
int idx = 0;
while (idx < replicaUrls.size()) {
if (isThisMyUrl(replicaUrls.get(idx))) {
replicaUrls.remove(idx);
} else {
idx++;
}
}
return replicaUrls;
}