抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Eureka 相关配置

Eureka 用户认证

我们启动了Eureka Server,然后在浏览器中输入http://localhost:8888/后,直接回车,就进入了spring cloud的服务治理页面,这么做在生产环境是极不安全的,下面,我们就给Eureka Server加上安全的用户认证。

配置Eureka server

导入POM依赖

在pom.xml中添加spring-boot-starter-seurity的依赖,该依赖为Eureka Server提供用户认证的能力。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
配置文件配置

修改 application.properties 增加以下配置

如何不进行配置,则默认用户名是 user ,默认密码是一个随机值,会在项目启动时打印出来。

注意 spring boot 2.x 以后配置方式

1
2
3
#eureka 安全认证
spring.security.user.name=admin
spring.security.user.password=admin

spring boot 2.x 以前的配置方式

1
2
3
4
#eureka 安全认证
security.user.name=admin
security.user.password=admin

关闭认证

在Eureka Server中添加如下配置类即可关闭Csrf校验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
public class EurekaConfiguration {
/**
* 2.1版本的security默认加上了 csrf 拦截, 所以需要通过重写方法, 把csrf拦截禁用
* 不写,客户端无法注册服务
*/
@EnableWebSecurity
static class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
super.configure(http);
}
}

}
启动项目

启动项目,访问 http://localhost:8888/ 即可看见身份验证的对话框,输出设置的用户名和密码即可进入。

输入用户名密码就可以正常访问了

客户端配配置

Eureka Server开启认证后,客户端默认情况下是无法注册当,也许认证才可以,当然配置很简单,只需修改defaultZone即可:http://${user.name}:${user.password}@${host}:${port}/eureka

1
eureka.client.serviceUrl.defaultZone=http://admin:admin@localhost:8888/eureka/

将订单服务以及用户服务修改后启动

Eureka 服务续约保活

​ 当客户端启动想 eureka 注册了本身服务列表后,需要隔段时间发送一次心跳给 eureka 服务端来证明自己还活着,当 eureka 收到这个心跳请求后才会知道客户端还活着,才会维护该客户端的服务列表信息。一旦因为某些原因导致客户端没有按时发送心跳给 eureka 服务端,这时候 eureka 可能会认为你这个客户端已经挂了,它就有可能把该服务从服务列表中删除掉。

原理

服务同步时间

在了解服务续约之前,我们先来理一理心跳,续约和剔除之间的关系,

我们先来说说续约和心跳的关系,服务续约分为两步

  • 第一步 是将服务节点的状态同步到注册中心,意思是通知注册中心我还可以继续工作,这一步需要借助客户端的心跳功能来主动发送。

  • 第二步 当心跳包到达注册中心的时候,那就要看注册中心有没有心动的感觉了,他有一套判别机制,来判定当前的续约心跳是否合理。并根据判断结果修改当前instance在注册中心记录的同步时间

接下来,服务剔除并不会和心跳以及续约直接打交道,而是通过查验服务节点在注册中心记录的同步时间,来决定是否剔除这个节点。

所以说心跳,续约和剔除是一套相互拮抗,共同作用的一套机制。

发送Renew请求

接下来,就是服务节点向注册中心发送续约请求的时候了

  1. 服务续约请求 客户端有一个DiscoverClient类,它是所有操作的门面入口。所以续约服务就从这个类的renew方法开始

  2. 发送心跳 服务续约借助心跳来实现,因此发给注册中心的参数和上一小节的心跳部分写到的一样,两个重要参数分别是服务的状态(UP)和lastDirtyTimeStamp

    • 如果续约成功,注册中心则会返回200的HTTP code

    • 如果续约不成功,注册中心返回404,这里的404并不是说没有找到注册中心的地址,而是注册中心认为当前服务节点并不存在。这个时候再怎么续约也不灵验了,客户端需要触发一次重新注册操作。

  3. 在重新注册之前,客户端会做下面两个小操作,然后再主动调用服务册流程。

    • 设置lastDirtyTimeStamp 由于重新注册意味着服务节点和注册中心的信息不同步,因此需要将当前系统时间更新到“lastDirtyTimeStamp”
    • 标记自己为脏节点
  4. 当注册成功的时候,清除脏节点标记,但是lastDirtyTimeStamp不会清除,因为这个属性将会在后面的服务续约中作为参数发给注册中心,以便服务中心判断节点的同步状态。

注册中心续约校验

考验注册中心灵验不灵验的时候到了,注册中心开放了一系列的HTTP接口,来接受四面八方的各种请求,他们都放在com.netflix.eureka.resources这个包下。只要客户端路径找对了,注册中心什么都能帮你办到。

  1. 接受请求 InstanceResource下的renewLease方法接到了服务节点的续约请求。

  2. 尝试续约 服务节点说:“万能的注册中心,请赐予我永生”。注册中心:“想得美,从现在算到下一次心跳间隔时间,如果你没来renew,就当你死了”。注册中心此时会做几样简单的例行检查,如果没有通过,则通通返回404,不接受申辩。

  • 小样你以前来注册过吗?没有?续约失败!带齐资料工作日前来办理注册!
  • 小样你是Unknown状态?回去回去,重新注册!
  1. 脏数据校验 如果续约校验没问题,接下来就要进行脏数据检查。到了服务续约最难的地方了,脏数据校验逻辑之复杂,如同这皇冠上的明珠。往细了说,就是当客户端发来的lastDirtyTimeStamp,晚于注册中心保存的lastDirtyTimeStamp时(每个节点在中心都有一个脏数据时间),说明在从服务节点上次注册到这次续约之间,发生了注册中心不知道的事儿(数据不同步)。这可不行,这搞得我注册中心的工作不好有序开展,回去重新注册吧。续约不通过,返回404。

配置

客户端配置
1
2
3
4
5
6
7
8
# 续约更新时间间隔,一般设置比续约到期时间少,该配置表示,每隔30秒就向服务端发送心跳。
eureka.lease-renewal-interval-in-seconds = 30

# 续约到期时间,可以单独给每个服务设置,如果在90秒(默认)内没有给服务发送心跳,则剔除该服务。
eureka.instance.lease-expiration-duration-in-seconds = 90

# 每隔30秒就去注册中心拉取注册表信息。
eureka.client.registry-fetch-interval-seconds = 30
服务端配置
1
2
3
4
5
6
#自我保护模式,当出现出现网络分区、eureka 在短时间内丢失过多客户端时, 会进入自我保护模式,即一个服务长时间没有发送心跳,eureka 也不会将其删 除,默认为 true
eureka.server.enable-self-preservation=true
#Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低 于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来
eureka.server.renewal-percent-threshold=0.85
#eureka server 清理无效节点的时间间隔,默认 60000 毫秒,即 60 秒
eureka.server.eviction-interval-timer-in-ms=60000

Eureka 自我保护机制

​ 默认Eureka是开启自我保护的。我们来做个测试,我们先启动三个工程,我们访问注册中心http://localhost:8888/,可以看到,实例是成功注册到中心的。此时我们将order服务关闭,刷新注册中心,我们会发现如下界面

​ 我们除了看到了一行红色的警告信息,还发现了一件神奇的事情,就是我们的服务实例虽然被kill了,但是在服务注册中心他还是存在的。这就是Eureka自我保护机制,他不会剔除已经挂掉的服务,他会认为这个服务是在尝试重新连接的。

​ 我们在开发过程中肯定是不希望这样的,不利于开发。我们可以关闭Eureka的自我保护机制(实际生产环境不建议关闭)。

注意:测试的时候需要使用 CMD 窗口使用 java -jar 的方式进行关闭测试,如果使用idea会出现测试不生效,因为idea关闭,会向微服务发送关闭通知,会进行停止处理,会像Eureka 发送下线通知。

服务端配置

1
2
3
4
#关闭保护机制,以确保注册中心将不可用的实例正确剔除
eureka.server.enable-self-preservation=false
#(代表是5秒,单位是毫秒,清理失效服务的间隔 )
eureka.server.eviction-interval-timer-in-ms=5000

客户端配置

1
2
3
4
5
6
7
# 心跳检测检测与续约时间
# 测试时将值设置设置小些,保证服务关闭后注册中心能及时踢出服务
# 配置说明
#  lease-renewal-interval-in-seconds 每间隔10s,向服务端发送一次心跳,证明自己依然”存活“
#  lease-expiration-duration-in-seconds 告诉服务端,如果我20s之内没有给你发心跳,就代表我“死”了,将我踢出掉。
eureka.instance.lease-renewal-interval-in-seconds=10
eureka.instance.lease-expiration-duration-in-seconds=20

测试

我们重新启动服务,然后关闭Order服务进行测试。

此时我们发现,红色警告变成了自我保护被关闭的警告,且实例被注册中心剔除,表明此时自我保护机制被关闭。

总结

​ Eureka的自我保护**是对微服务实例的地址信息进行保护,避免因一些意外情况将正常节点直接剔除。

健康检测

​ 在Spring boot应用中,要实现可监控的功能,依赖的是 spring-boot-starter-actuator 这个组件。它提供了很多监控和管理你的spring boot应用的HTTP或者JMX端点,并且你可以有选择地开启和关闭部分功能。当你的spring boot应用中引入下面的依赖之后,将自动的拥有审计、健康检查、Metrics监控功能。

客户端配置

导入POM依赖

pom文件中添加如下依赖

1
2
3
4
5
<!--健康检查依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
查看信息

他的什么都不变,我们来访问一下这个接口 http://localhost:8083/actuator/health
我们看到了一个很简短的健康报告

1
{"status":"UP"}

要想查看详细的应用健康信息需要配置management.endpoint.health.show-details 的值为always,配置之后我们再次访问 http://localhost:8083/actuator/health,获取的信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"status": "UP",
"components": {
"discoveryComposite": {
"status": "UP",
"components": {
"discoveryClient": {
"status": "UP",
"details": {
"services": []
}
},
"eureka": {
"description": "Eureka discovery client has not yet successfully connected to a Eureka server",
"status": "UP",
"details": {
"applications": {}
}
}
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 161060220928,
"free": 49096417280,
"threshold": 10485760
}
},
"hystrix": {
"status": "UP"
},
"ping": {
"status": "UP"
},
"refreshScope": {
"status": "UP"
}
}
}

从上面的应用的详细健康信息发现,健康信息包含磁盘空间、redis、DB,启用监控的这个spring boot应用确实是连接了redis和oracle DB,actuator就自动给监控起来了,确实是很方便、很有用。

经过测试发现,details中所有的监控项中的任何一个健康状态是DOWN,整体应用的健康状态也是DOWN

自定义健康检查

​ 有时候需要提供自定义的健康状态检查信息,你可以通过实现HealthIndicator的接口来实现,并将该实现类注册为spring bean。你需要实现其中的health()方法,并返回自定义的健康状态响应信息,该响应信息应该包括一个状态码和要展示详细信息。例如,下面就是一个接口HealthIndicator的实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class DBHealthIndicator implements HealthIndicator {
//模拟数据库挂掉
public static volatile boolean DB_HEALTH_STATUS = true;

@Override
public Health health() {
Health health = null;
if (DB_HEALTH_STATUS) {
health = Health.up().build();
} else {
health = Health.down().withDetail("error message", "db is not health").build();
}
return health;
}
}

写一个controller 来进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
public class DBHealthController {

@RequestMapping("/db/{status}")
public String dbHealth(@PathVariable("status") String status) {
if ("up".equalsIgnoreCase(status)) {
DBHealthIndicator.DB_HEALTH_STATUS = true;
} else {
DBHealthIndicator.DB_HEALTH_STATUS = false;
}
return "Set successfully";
}
}
测试

请求 http://localhost:8083/db/down 将数据库设置为fasle,通过http://localhost:8083/actuator/health 查看健康状态

然后 设置为up在测试

Eureka健康检测

​ Eureka 默认的健康检测只是你校验服务连接是否是 UP 还是 DOWN 的,然后客户端只会调用状态为 UP 状态的服务,但是有的情况下,虽然服务连接是好的,但是有可能这个服务的某 些接口不是正常的,可能由于需要连接 Redis,mongodb 或者 DB 有问题导致接口调用失败, 所以理论上服务虽然能够正常调用,但是它不是一个健康的服务。所以我们就有必要对这种 情况做自定义健康检测

客户端配置文件
1
2
#开启Eureka的健康检测
eureka.client.healthcheck.enabled=true

这时,启动自己的服务,通过http://localhost:port/actuator/health访问就可以得到服务的健康状态信息,当这个配置设置为false时,服务将不会把健康状态传递给Eureka,那么Eureka就不会再更新Status信息,但是此时仍能够通过上面的地址获取这个真实的状态信息。

测试

请求 http://localhost:8083/db/down 将数据库设置为fasle

刷新Eureka健康界面,发现一段时间后服务变为了down

请求 http://localhost:8083/db/down 将数据库设置为true,一段时间后有变成了正常

总结

实例的健康检查则是微服务与Eureka注册中心交互正常的情况下,微服务因自己内部原因无法正常对外提供服务,主动告诉注册中心自己出了问题,让注册中心别发新的请求过来。

Eureka 服务下线

​ 比如有些情况是服务主机意外宕机了,也就意味着服务没办法给 eureka 心跳信息了,但是 eureka 在没有接受到心跳的情况下依赖维护该服务 90s,在这 90s 之内可能会有客户端调用 到该服务,这就可能会导致调用失败。所以我们必须要有一个机制能手动的立马把宕机的服 务从 eureka 服务列表中清除掉,避免被服务调用方调用到。

确定需要强行剔除的服务

执行接口

Eureka 提高了下线接口 用delete 方式请求

http://{ip}:{port}/eureka/apps/服务名/应用id

方便复制 http://{ip}:{port}/eureka/apps/ORDER-SERVER/DESKTOP-0VIUDQU:order-server:8083

效果

刷新eureka 发现服务消失了

但是我们没有停止服务,等一会因为心跳会重新注册的

注册服务显示IP端口号

Spring cloud 显示 INSTANCE-ID 如果以IP + 端口号的形式显示,会更清析的定位每个服务所在的机器节点的状态。

​ 服务提供者向 Eureka 注册中心注册,默认以 hostname 的形式显示,Eureka 服务页面显示的服务是机器名:端口,并不是IP+端口的形式 ,可以通过修改服务提供者配置自己的 IP 地址,并显示在 Eureka 的注册列表中。

直接配置

1
2
3
4
#注册时使用ip而不是主机名
eureka.instance.prefer-ip-address=true
#指定此实例的ip
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

注: 如果只是配置了eureka.instance.prefer-ip-address=true,而不配置eureka.instance.instance-id,那还是显示localhost,但ip地址是可以访问得了。

效果如下:

手工指定IP

添加以下配置

1
2
3
4
# 指定此实例的ip
eureka.instance.ip-address = 127.0.0.1
# 注册时使用ip而不是主机名
eureka.instance.prefer-ip-address = true

多网卡选择问题

问题场景

​ 服务器上分别配置了eth0, eth1和eth2三块网卡,只有eth1的地址可供其它机器访问,eth0和eth2的 IP 无效。在这种情况下,服务注册时Eureka Client会自动选择eth0作为服务ip, 导致其它服务无法调用。

问题原因

​ 由于官方并没有写明Eureka Client探测本机IP的逻辑,所以只能翻阅源代码。Eureka Client的源码在eureka-client模块下,com.netflix.appinfo包下的InstanceInfo类封装了本机信息,其中就包括了IP地址。在 Spring Cloud 环境下,Eureka Client并没有自己实现探测本机IP的逻辑,而是交给Spring的InetUtils工具类的findFirstNonLoopbackAddress()方法完成的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public InetAddress findFirstNonLoopbackAddress() {
InetAddress result = null;
try {
// 记录网卡最小索引
int lowest = Integer.MAX_VALUE;
// 获取所有网卡
for (Enumeration<NetworkInterface> nics = NetworkInterface
.getNetworkInterfaces(); nics.hasMoreElements();) {
NetworkInterface ifc = nics.nextElement();
if (ifc.isUp()) {
log.trace("Testing interface: " + ifc.getDisplayName());
if (ifc.getIndex() < lowest || result == null) {
lowest = ifc.getIndex(); // 记录索引
}
else if (result != null) {
continue;
}

// @formatter:off
if (!ignoreInterface(ifc.getDisplayName())) { // 是否是被忽略的网卡
for (Enumeration<InetAddress> addrs = ifc
.getInetAddresses(); addrs.hasMoreElements();) {
InetAddress address = addrs.nextElement();
if (address instanceof Inet4Address
&& !address.isLoopbackAddress()
&& !ignoreAddress(address)) {
log.trace("Found non-loopback interface: "
+ ifc.getDisplayName());
result = address;
}
}
}
// @formatter:on
}
}
}
catch (IOException ex) {
log.error("Cannot get first non-loopback address", ex);
}

if (result != null) {
return result;
}

try {
return InetAddress.getLocalHost(); // 如果以上逻辑都没有找到合适的网卡,则使用JDK的InetAddress.getLocalhost()
}
catch (UnknownHostException e) {
log.warn("Unable to retrieve localhost");
}

return null;
}

​ 通过源码可以看出,该工具类会获取所有网卡,依次进行遍历,取ip地址合理、索引值最小且不在忽略列表的网卡的ip地址作为结果。如果仍然没有找到合适的IP, 那么就将InetAddress.getLocalHost()做为最后的fallback方案。

解决方案

忽略指定网卡

通过上面源码分析可以得知,spring cloud肯定能配置一个网卡忽略列表。通过查文档资料得知确实存在该属性:

1
spring.cloud.inetutils.ignored-interfaces[0]=eth0 # 忽略eth0, 支持正则表达式

因此,第一种方案就是通过配置application.properties让应用忽略无效的网卡。

配置host

​ 当网查遍历逻辑都没有找到合适ip时会走JDK的InetAddress.getLocalHost()。该方法会返回当前主机的hostname, 然后会根据hostname解析出对应的ip。因此第二种方案就是配置本机的hostname和/etc/hosts文件,直接将本机的主机名映射到有效IP地址。

手工指定IP(推荐)

添加以下配置:

1
2
3
4
# 指定此实例的ip
eureka.instance.ip-address=192.168.x.x
# 注册时使用ip而不是主机名
eureka.instance.prefer-ip-address=true

Eureka 高可用

​ 高可用是在服务架构设计中,频繁出现的词汇。微服务架构里自然也一样需要保证服务的高可用性,所以本小节将简单说明一下Eureka是如何实现高可用的。

​ 在实际生产环境中服务器是很脆弱的,单台服务器肯定是无法满足高可用的需求,为了保证高可用性我们通常会准备多台服务器。但可以发现上文中所搭建的eureka server是单机的,若这个eureka server宕机,则会导致与之关联的全部微服务发生故障。

在微服务中我们要考虑到发生故障的情况,所以说对服务注册中心也要进行高可用部署。

官方对于Eureka 高可用的描述:

Eureka can be made even more resilient and available by running multiple instances and asking them to register with each other. In fact, this is the default behaviour, so all you need to do to make it work is add a valid serviceUrl to a peer, e.g.

​ 就是通过多个eureka实例进行互相注册,然后修改每个实例的serviceUrl即可。Eureka Server的高可用实际上就是将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组互相注册的服务注册中心,以实现服务清单的互相同步,达到高可用的效果。

单点配置

之前eureka-server的单点配置

1
2
3
4
5
6
7
eureka.instance.hostname=localhost
#暴漏的注册地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#是否注册到eureka
eureka.client.register-with-eureka=false
#是否从eureka来取注册信息
eureka.client.fetch-registry=false

让服务注册中心不注册自己。

Eureka 服务端配置

创建两个application.propertites 文件,启动两个eureka-server,让他们互为备份。

application-8888.propertites
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server.port=8888
spring.application.name=cloud-eureka-server
# 实例的主机名称
eureka.instance.hostname=localhost
#暴漏的注册地址 指向另一个eureka-server的url
eureka.client.serviceUrl.defaultZone=http://admin:admin@${eureka.instance.hostname}:9999/eureka/
#当然这个默认就是true,表示向eureka注册自己
eureka.client.register-with-eureka=true
#是否从eureka来取注册信息
eureka.client.fetch-registry=true
#eureka 安全认证
spring.security.user.name=admin
spring.security.user.password=admin


#自我保护模式,当出现出现网络分区、eureka 在短时间内丢失过多客户端时, 会进入自我保护模式,即一个服务长时间没有发送心跳,eureka 也不会将其删 除,默认为 true
eureka.server.enable-self-preservation=true
#Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低 于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来
eureka.server.renewal-percent-threshold=0.85
#eureka server 清理无效节点的时间间隔,默认 60000 毫秒,即 60 秒
eureka.server.eviction-interval-timer-in-ms=60000
application-9999.propertites
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server.port=9999
spring.application.name=cloud-eureka-server
# 实例的主机名称
eureka.instance.hostname=localhost
#暴漏的注册地址 指向另一个eureka-server的url
eureka.client.serviceUrl.defaultZone=http://admin:admin@${eureka.instance.hostname}:8888/eureka/
#当然这个默认就是true,表示向eureka注册自己
eureka.client.register-with-eureka=true
#是否从eureka来取注册信息
eureka.client.fetch-registry=true
#eureka 安全认证
spring.security.user.name=admin
spring.security.user.password=admin


#自我保护模式,当出现出现网络分区、eureka 在短时间内丢失过多客户端时, 会进入自我保护模式,即一个服务长时间没有发送心跳,eureka 也不会将其删 除,默认为 true
eureka.server.enable-self-preservation=true
#Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低 于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来
eureka.server.renewal-percent-threshold=0.85
#eureka server 清理无效节点的时间间隔,默认 60000 毫秒,即 60 秒
eureka.server.eviction-interval-timer-in-ms=60000
启动测试

通过spring.profiles.active属性来启动不同的环境,当然生产上肯定就是二台不同的服务了,这边只是在单机上模拟Eureka Server的高可用,启动的时候指定不一样的配置文件,

1
2
java -jar eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=8888
java -jar eureka-server-1.0-SNAPSHOT.jar --spring.profiles.active=9999
访问8888端口

访问9999端口

注意

Eureka高可用部署,启动多个注册中心后,节点均出现在unavailable-replicas,查阅各类资料测试,提供方案

  1. eureka.client.serviceUrl.defaultZone配置项的地址,不能使用localhost,要使用ip或域名

  2. spring.application.name要一致(这个个人测试默认不配也可以)

  3. fetch-registry、register-with-eureka 都需要设置为true,要不然集群服务器数据不同步,目前Spring Cloud 版本为 Hoxton.SR4

  4. 默认情况下,eureka client使用主机名(hostName)向注册中心注册。

  5. 当prefer-ip-address: true时 ,client使用的是ip向服务中心注册 ,但是默认获取的ip是 127.0.0.1。默认情况下 当 这个获取的ip 和 hostName 不同时 ,则产生不可用分片提示信息(unavailable-replicas),并且集群间的数据不会同步。

  6. 所以要么指定 两个ip相同 ,就不会有提示了(指定ip-address和hostname相同)。

客户端配置

服务提供者消费者配置也要做一些修改,这边以服务提供者为例,其实严格意义上一个服务可以做服务提供者也可以做服务消费者

1
2
3
4
5
6
7
8
9
10
11
12
server.port=8083
spring.application.name=order-server
eureka.client.serviceUrl.defaultZone=http://admin:admin@127.0.0.1:8888/eureka/,http://admin:admin@127.0.0.1:9999/eureka/
# 续约更新时间间隔,一般设置比续约到期时间少,该配置表示,每隔30秒就向服务端发送心跳。
eureka.lease-renewal-interval-in-seconds=10
# 续约到期时间,可以单独给每个服务设置,如果在90秒(默认)内没有给服务发送心跳,则剔除该服务。
eureka.instance.lease-expiration-duration-in-seconds=90
# 每隔30秒就去注册中心拉取注册表信息。
eureka.client.registry-fetch-interval-seconds=30
#开启Eureka的健康检测
eureka.client.healthcheck.enabled=true

此时如果断开8888,则order也会向9999上注册。所以依然能够访问到order服务,从而实现服务注册中心的高可用。

评论