Eureka 服务发现Discovery
actuator微服务信息完善
主机名称:服务名称修改 访问信息有IP提示
我们可以配置Eureka Client 让 Eureka Client 在Eureka Server上注册的地址和名称,可以准确的定位到是哪台服务器的IP地址,以及该微服务的名称,有利于排查问题
修改8001 和8002 的 application.yml 在 eureka:client下添加配置信息,重新启动后,在可以看到变化
instance:
instance-id: payment8001
prefer-ip-address: true # 访问路径可以显示IP
# eureka 相关配置文件
eureka:
client:
# 表示将自己注册进入 Eureka Server 默认为true
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为true,集群时必须设置为true 才能配合 ribbon 使用 负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
instance-id: payment8001
prefer-ip-address: true # 访问路径可以显示IP
服务发现 Discovery
功能
对于注册进Eureka里面的微服务,可以通过服务发现来获取该微服务的信息。
修改内容
修改 Payment8001 的Controller
@GetMapping("/discovery")
public DiscoveryClient discovery() {
// 获取注册进入Eureka 服务列表的信息
List<String> services = discoveryClient.getServices();
List<ServiceInstance> instancesList = new ArrayList<>();
services.forEach(item -> {
log.info("*****element:" + item);
// 根据微服务的具体名称获取 获取微服务的相关信息
instancesList.addAll(discoveryClient.getInstances(item));
instancesList.forEach(instances -> {
// 微服务 serviceId
String serviceId = instances.getServiceId();
// 微服务 主机名
String host = instances.getHost();
// 微服务 端口号
int port = instances.getPort();
// 微服务 uri 地址
URI uri = instances.getUri();
log.info(serviceId + "\t" + host + "\t" + port + "\t" + uri);
});
});
return this.discoveryClient;
}
修改 Payment8001 的主启动类 @EnableDiscoveryClient
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class Payment8001Application {
public static void main(String[] args) {
// 时区设置
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
SpringApplication.run(Payment8001Application.class, args);
}
}
自测
查询到注册至Eureka的微服务
Eureka 自我保护
故障现象
概述:保护模式主要用于一组客户端和 Eureka Server之间存在网络分区场景下的保护,一旦进入保护模式, Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。
如果在 Eureka Server的首页上看到一下提示,说明 Eureka Server已经进入了保护模式 EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
导致原因
为什么会产生Eureka自我保护机制:为了防止Eureka Client 可以正常运行,但是与Eureka Server网络不通的情况下,Eureka Server不会立即将Eureka Client服务剔除
什么是自我保护模式:默认情况下,如果Eureka Server在一定时间内没有接收到某个微服务的心跳,Eureka Server将会注销该实例,但是当网络分区故障发生(延迟、卡顿、拥挤)时,微服务与Eureka Server之间无法正常通信,以上行为可能变得危险了,因为微服务本身是健康的,此时本不应该立即注销这个微服务。Eureka 通过“自我保护模式”来解决这个问题–当Eureka Server节点在短时间内丢失过多客户端时(可能发生网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例,它的设计哲学就是宁可保留错误的服务注册信息,也不盲目的注销任何可能健康的服务实例。
综上,自我保护模式是一种对网路异常的安全保护模式,它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留),也不盲目的注销任何可能健康的服务实例。使用自我保护模式,可以让Eureka 集群更加的健壮、稳定。
某时刻某一个微服务不可用了,Eureka 也不会立刻清理,依旧会对该微服务的信息进行保存,这属于CAP里面的AP分支
如何禁止自我保护
注册中心 Eureka Server端 7001 先改成单机模式,然后在application.yml添加如下配置
server:
# 出厂默认是开启自我保护机制的,eureka.server.enable-self-preservation=false 可以禁用自我保护模式
# 关闭自我保护机制,保证不可用服务被及时清除
enable-self-preservation: false
# 过期实例应该启动并运行的时间间隔, 也就是清理无效节点的时间间隔 单位为毫秒, 默认60s 改成1s
eviction-interval-timer-in-ms: 1000
完整application.yml文件
server:
port: 7001
# eureka 服务端的实例名称
eureka:
instance:
hostname: eureka7001.com # eureka 服务端的实例名称
client:
# false 表示不向注册中心注册自己
register-with-eureka: false
# false 表示自己就是注册中心,职责是维护服务实例,无需去检索服务
fetch-registry: false
# 设置与eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
service-url:
# 7001与7002 相互守望 相互注册
defaultZone: http://eureka7001.com:7001/eureka/
server:
# 出厂默认是开启自我保护机制的,eureka.server.enable-self-preservation=false 可以禁用自我保护模式
# 关闭自我保护机制,保证不可用服务被及时清除
enable-self-preservation: false
# 过期实例应该启动并运行的时间间隔, 也就是清理无效节点的时间间隔 单位为毫秒, 默认60s 改成1s
eviction-interval-timer-in-ms: 1000
注册中心 Eureka Client端 8001 、8002 先改成单机模式指向7001,然后在application.yml添加如下配置
# eureka 客户端 服务端发送心跳的时间间隔,单位秒 默认 30s
lease-renewal-interval-in-seconds: 1
# eureka 服务端在收到最后一次心跳后等待时间上限,单位是秒默认是90s 超时将会清除微服务
lease-expiration-duration-in-seconds: 2
完整application.yml文件
server:
port: 8001
spring:
application:
name: cloud-payment-service # 微服务名称
datasource:
# 当前数据源操作类型
type: com.alibaba.druid.pool.DruidDataSource
# mysql 驱动类
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/db2020?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
#flyway 不指定默认排序
flyway:
out-of-order: true
# 先关闭热部署,老是重启电脑卡有点烦
devtools:
add-properties: false
mybatis:
mapper-locations: classpath*:mapper/*.xml
# 所有Entity类所在的包
type-aliases-package: com.zjt.cloud.domain
#configuration:
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
level:
com.zjt.cloud.dao: debug
org:
apache:
ibatis: info
# eureka 相关配置文件
eureka:
client:
# 表示将自己注册进入 Eureka Server 默认为true
register-with-eureka: true
# 是否从 Eureka Server 抓取已有的注册信息,默认为true,集群时必须设置为true 才能配合 ribbon 使用 负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: payment8001
prefer-ip-address: true # 访问路径可以显示IP
# eureka 客户端 服务端发送心跳的时间间隔,单位秒 默认 30s
lease-renewal-interval-in-seconds: 1
# eureka 服务端在收到最后一次心跳后等待时间上限,单位是秒默认是90s 超时将会清除微服务
lease-expiration-duration-in-seconds: 2
测试
先开启 7001 然后开启 8001、8002 ,微服务在Eureka Server正常显示后关闭8001 8001会被清除掉
打开官方网站 https://github.com/Netflix/eureka/wiki Eureka停止更新了😭。下节继续跟着教程学习cloud 整合Zookeeper代替Eureka