概述
先上配置文件了,刚开始是直接指定两个配置中心地址,发现两个中心要按一定顺序放,这就有点坑了,我们根本不知道哪个先放前面,尝试几次只有最后一个服务注册中心有交,然后就想到改变一种方法实现
eureka:
client:
prefer-same-zone-eureka: true
registerWithEureka: true
fetch-registry: true
# 假设指定region为上海
region: sh
availability-zones:
#假设上海下面有两个region
sh: pudong,xuhui
serviceUrl:
# defaultZone: http://user:password@192.168.11.45:8761/eureka/
pudong: http://user:password@192.168.11.45:8761/eureka/
xuhui: http://user:password@192.168.11.46:8761/eureka/
instance:
prefer-ip-address: true #在eureka里显示IP,下一行是显示地址信息的格式
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: 192.168.11.126
secure-port: 5888
metadata-map:
zone: xuhui
serviceUrl是真正的属性,service-url的配置内容是map,map的内容是可以自己发挥的,只要是key: value格式就行(注意有个空格)。有很多map类型的配置,比如availabilityZones,metadata-map都是的,内容虽然是key: value格式,但是都是可以自由发挥。其中metadata-map比较特殊,里面有个zone的属性,会被eureka client解析,当成客户端默认指向的zone来处理。
注册中心选择逻辑:
1. 如果prefer-same-zone-eureka为false,按照service-url下的 list取第一个注册中心来注册,并和其维持心跳检测。不会再向list内的其它的注册中心注册和维持心跳。只有在第一个注册失败的情况下,才会依次向其它的注册中心注册,总共重试3次,如果3个service-url都没有注册成功,则注册失败。每隔一个心跳时间,会再次尝试。
2. 如果prefer-same-zone-eureka为true,先通过region取availability-zones内的第一个zone,然后通过这个zone取service-url下的list,并向list内的第一个注册中心进行注册和维持心跳,不会再向list内的其它的注册中心注册和维持心跳。只有在第一个注册失败的情况下,才会依次向其它的注册中心注册,总共重试3次,如果3个service-url都没有注册成功,则注册失败。每隔一个心跳时间,会再次尝试。
所以说,为了保证服务注册到同一个zone的注册中心,一定要注意availability-zones的顺序,必须把同一zone写在前面
2. 服务调用的配置文件
eureka:
instance:
metadata-map:
zone: pudong
服务消费者和服务提供者分别属于哪个zone,均是通过eureka.instance.metadata-map.zone来判定的。
服务消费者会先通过ribbon去注册中心拉取一份服务提供者的列表,然后通过eureka.instance.metadata-map.zone指定的zone进行过滤,过滤之后如果同一个zone内的服务提供者有多个实例,则会轮流调用。
只有在同一个zone内的所有服务提供者都不可用时,才会调用其它zone内的服务提供者。
再看源码 getAvailabilityZones()和getEurekaServerServiceUrls()两个方法的实现。现在向两个服务注册中心添加地址的时候,为什么不能用空格了吧,并且其它符号更不行,
// 根据region,从availabilityZones这个Map中获取key值对应的配置。
// availabilityZones是通过eureka.client.availability-zones配置的,
// 可以配置多个availabilityZones,key表示region,value表region对应的zones
// 假设有多个zones,用逗号隔开。
// region通过eureka.client.region来设置,假设不设置,默认为"us-east-1c"。
public String[] getAvailabilityZones(String region) {
String value = (String)this.availabilityZones.get(region);
if (value == null) {
value = "defaultZone";
}
return value.split(",");
}
// 根据zone来获取serviceUrls,假设用逗号隔开会拆分成数组。
public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = (String)this.serviceUrl.get(myZone);
if (serviceUrls == null || serviceUrls.isEmpty()) {
serviceUrls = (String)this.serviceUrl.get("defaultZone");
}
if (!StringUtils.isEmpty(serviceUrls)) {
String[] serviceUrlsSplit = StringUtils.commaDelimitedListToStringArray(serviceUrls);
List<String> eurekaServiceUrls = new ArrayList(serviceUrlsSplit.length);
String[] var5 = serviceUrlsSplit;
int var6 = serviceUrlsSplit.length;
for(int var7 = 0; var7 < var6; ++var7) {
String eurekaServiceUrl = var5[var7];
if (!this.endsWithSlash(eurekaServiceUrl)) {
eurekaServiceUrl = eurekaServiceUrl + "/";
}
eurekaServiceUrls.add(eurekaServiceUrl.trim());
}
return eurekaServiceUrls;
} else {
return new ArrayList();
}
}
下面这一行配置要注意注册中心的顺序, 否则只有一例生效或者报错,原因就是后面的循环拿值没对应上,分析如下:
serviceUrl:
defaultZone: http://user:pass@192.168.11.46:8761/eureka/,http://user:pass@192.168.11.45:8761/eureka/
Eureka会先获取region,如果我们没有设置region,region默认值为"us-east-1c",然后会根据这个region去获取对应的availabilityZones。
然后循环availabilityZones的值,使用每个zone来调用getEurekaServerServiceUrls,获取serviceUrl,最终形成一个zone为key,serviceUrls(因为可能一个zone有多个serviceUrl)列表为value的map。
在使用serviceUrl的时候,使用两重循环:
会按照顺序,逐个取availabilityZones的zone,从map中获取serviceUrls,在逐个循环serviceUrls,来判断是否可达,如果任意serviceUrl可达则停止,否则一致尝试到最后。
如果availabilityZones为空,或者根据它的值取不到serviceUrls,则会返回key为defaultZone的serviceUrls。如果我们也指定了defaultZone对应的serviceUrls,会覆盖原来的defaultZone,否则使用默认的http:// localhost:8761/eureka。
如果想用自己的zone,该如何设置。
首先要设置region,不设置也可以,不设置就按照"us-east-lc"来组织后面的设置。并且根据region一定要能获取availabilityZones的zone值,如果没有就会默认使用defaultZone。我们假设自己设置region为china。然后需要设值availabilityZones,假设有两个sh:pudong,xuhui。然后在serviceUrls中设置pudong: xxxx 换行xuhui: xxxx,分别指向两个服务,
坑:注意getAvailabilityZones这个方法不会trim(),所以逗号后面不要有空格,不然用带空格的key会找不到serviceUrl,这个实现实在有点掉价。而getEurekaServerServiceUrls方法是加了trim()方法的 ,逗号后面可以有空格。
然后启动之后就会把服务注册到两个服务中心,互不影响的两个服务中心,当然如果是集成高可用的服务注册中心,注册中心又是互相注册同步过,那么服务只需要注册任意一个中心,两个服务中心都是可以看到这个服务的。
配置这种事情,简单也可以用,复杂点也能很好发挥作用。有时间就应该慢慢深入研究。
最后
以上就是清爽小懒虫为你收集整理的Eureka高可用注册中心通过defaultZone深入理解zone和serviceUrl的全部内容,希望文章能够帮你解决Eureka高可用注册中心通过defaultZone深入理解zone和serviceUrl所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复