有分布式应用开发经验的读者应该能够看出,前 文 编写的单节点 Eureka Server 并不适合线上 生产环境。Eureka Client 会定时连接 Eureka Server, 获取服务注册表中的信息并缓存在本地。
微服务在消费远程 API 时总是使用本地 缓存中的数据。因此一般来说,即使Eureka Server 发生宕机,也不会影响到服务之间的调用。
但如果 Eureka Server 宕机时, 某些微服务也出现了不可用的情况, Eureka Client 中的缓存若不被更新, 就可能会影响到微服务的调用, 甚至影响到整个应用系统的高可用性。
因此, 在生产环境中, 通常会部署一个高可用的Eureka Server 集群。
Eureka Server 可以通过运行 多个实例并相互注册的方式实现高可用部署, Eureka Server 实例会彼此增量地同步信息, 从而确保所有节点数据一致。
事实上, 节点之间相互注册是 EurekaServer 的默认行为,还记得前文编写单节点 Eureka Server 时,
额外配置了eureka.client.registerWithEureka=false 、eureka.client.fetchRegistry=false 吗?
本节在前文的基础上, 构建一个双节点Eureka Server 集群。
1. 复制项目discovery-eureka
2. 配置系统的hosts, Windows系统的hosts 文件路径是C:\Windows\System32\drivers\etc\hosts;
Linux 及 Mac OS 等系统的文件路径是 /etc/hosts。
127.0.0.1 peer1
127.0.0.1 peer2
3. 将 application.yml修改如下:让两个节点的 Eureka Server 相互注册。
#server:
# port: 8761 # 指定该Eureka实例的端口
# enableSelfPreservation: false
#eureka:
# client:
# registerWithEureka: false
# fetchRegistry: false
# serviceUrl:
# defaultZone: http://localhost:8761/eureka/
spring:
application:
name: discovery-eureka
eureka:
client:
registerWithEureka: true
fetchRegistry: true
---
spring:
profiles: peer1 # 指定profile=peer1
server:
port: 8761
eureka:
instance:
hostname: peer1 # 指定当profile=peer1时,主机名是peer1
client:
serviceUrl:
defaultZone: http://peer2:8762/eureka/ # 将自己注册到peer2这个Eureka上面去
registerWithEureka: true
fetchRegistry: true
---
spring:
profiles: peer2
server:
port: 8762
eureka:
instance:
hostname: peer2
client:
registerWithEureka: true
fetchRegistry: true
serviceUrl:
defaultZone: http://peer1:8761/eureka/
测试
1. 打包项目,并使用 以下命令启动两个Eureka Server 节点。
java -jar discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.actiVe=peer1
java -jar discovery-eureka-ha-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
通过spring.profiles.active 指定使用哪个profile 启动。
2. 访问http://peer1:8761 , 会发现 "registered-replicas" 中巳有peer2 节点;
3. 同理, 访问http://peer2:8762 , 也能发现其中的 "registered-replicas" 有 peerl 节点, 如图4-6 所示。
在前面的示例中, Eureka Server 是允许匿名访问的, 本节来构建一个需要登录才能访问的 Eureka Server。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
security:
basic:
enabled:true #开启基 于HTTP basic的 认证
user:
name: user #配置登录的账号是user
password: password123 #配置登录的密码是 paswsord123
这样就为 Eureka Server 添加了基于HTTP basic 的认证。如果不设置这段内容 ,账号默认是 user , 密码是一个随机值, 该值会在启动时打印出来。