Eureka是微服务中的服务发现组件,微服务消费者和提供者在启动的时候会将自己的信息注册到服务发现组件当中,当消费者微服务需要调用生产者微服务的时候,则会从服务发现组件当中找到提供者的地址并进行调用
自定义Eureka健康检测
如果在eureka server上的微服务不可用了,那么继续进行调用显然就是不合理的,这时候Eureka会为我们去除无效的微服务(开启自我保护后将不会去除无效的微服务),但是有时候,微服务本身是没有问题的,而是因为依赖的第三方出现问题从而导致了微服务的不可用,这种时候调用依旧是不可用的,所以我们需要通过创建自定义Eureka健康检测来校验微服务是否可用。
构建依赖环境
在服务消费者和提供者处添加依赖的maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--健康监测依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在启动项添加注解
将服务消费者和提供者设置为eureka client,在项目启动类中添加注解
@EnableEurekaServer
创建一个改变微服务健康状态的控制器
@RestController
public class UserController {
public static boolean isDB = true;
@GetMapping(value = "/setIsDB/{isDB}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public void setIsDB(@PathVariable boolean isDB) {
this.isDB = isDB;
}
}
创建HealthIndicator
这是一个简单的检测类,通过一定时间对自身微服务的状态进行检测
重写health方法,根据自己相关业务的要求对health对象的状态进行设置
@Component
public class MyHealthIndicator implements HealthIndicator {
@Override
public Health health() {
if(UserController.isDB){
return new Health.Builder(Status.UP).build();
} else{
return new Health.Builder(Status.DOWN).build();
}
}
}
编写健康检查处理器
Eureka客户端和服务端通过心跳的方式进行连接通信,服务端通过心跳机制对client客户端的状态进行检测,心跳机制会主动检测自定义健康检查处理器,并将健康状态传递给服务发现者
@Component
public class MyHealthCheckHandler implements HealthCheckHandler {
@Autowired
private MyHealthIndicator myHealthIndicator;
@Override
public InstanceInfo.InstanceStatus getStatus(InstanceInfo.InstanceStatus instanceStatus) {
Status status = myHealthIndicator.health().getStatus();
if (status.equals(Status.UP)){
return InstanceInfo.InstanceStatus.UP;
} else {
return InstanceInfo.InstanceStatus.DOWN;
}
}
}
这时候,我们通过对微服务的调用来改变微服务的健康状况,最后我们可以在Eureka seerver中查看当前被修改微服务的状态
Eureka的高可用
对于Eureka的高可用来说,我在网上看了一些资料,大多都是照本宣科,很多我关注的和不解的问题都没有很好的解释,所以本文针对我之前一些不理解的地方,我会进行比较深入的分析,如果有不对的地方也欢迎大家和我进行探讨
在一个项目下面实现Eureka的高可用
实现一个项目下的高可用,实际就是对yml文件进行配置,设置两个不同的端口号,通过profiles的方式分别进行启动,此处我通过代码简单的说下
spring:
application:
name: new-eureka
---
spring:
#指定profiles为peer1
profiles: peer1
server:
port: 8761
eureka:
instance:
#设置主机名+端口访问实力
hostname: peer1
client:
#Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。
#register-with-eureka: false
#fetch-registry: false
service-url:
#将自己注册到peer2这个eureka上面
defaultZone: http://localhost:8762/eureka/ #指定eureka服务器的地址
#server:
#关闭自我保护,如果没有关闭自我保护则会导致客户端继续访问已停微服务
#开启自我保护后,如果注册表里的服务关闭了,Eureka Server不会注销该服务,会等待服务自动修复
#为了让其有精准的 CP健康检查,可以关闭自我保护功能,让其剔除不健康节点。
#enable-self-preservation: false
#定时清理服务器
#eviction-interval-timer-in-ms: 5000
---
spring:
#指定profiles为peer1
profiles: peer2
server:
port: 8762
eureka:
instance:
#设置主机名+端口访问实力
hostname: peer2
client:
#Eureka服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为。
#register-with-eureka: false
#fetch-registry: false
service-url:
#将自己注册到peer2这个eureka上面
defaultZone: http://localhost:8761/eureka/ #指定eureka服务器的地址
在我最初的时候是采用创建三个yml文件的方式,但是启动一直报错,我的另外两个配置文件没有起作用,所以只能改成这种三段式,但是之前不起作用的配置原因我并没有找到
这种方式需要在host中修改文件
最后是通过不同的命令对eureka进行启动,采用不同的配置文件
配置完成后,启动eureka服务端和服务消费者和服务发现者
此处基本完成了Eureka的高可用,下面我来说下配置Eureka高可用中比较关键的问题
Q1:关于EUREKA SERVER之间的相互复制
A1:在上面的配置文件中,我将8761注册到端口8762的Eureka上,将8762端口的Eureka注册到8761上,完成了Eureka Server之间的相互添加的操作,此处我创建了一个微服务,Eureka注册地址写的是8761端口的,但是当我们在访问8762端口下的Eureka server时,发现也是可以看到,说明Eureka之间的信息是可以互相进行复制操作的
Q2:关于微服务中client失效后,Eureka的处理逻辑
A2:假设我有两个server,两个Client,此时client1注册在server1上,client2注册在server2上,当client1失效后,server1并不会马上移除lcient1,而是与client1在进行3次心跳失败后,将会注销该微服务,但是如果Eureka开启了自我保护后,那么该client1将不会被删除,只是无法进行访问,但是当有新的client不断被注册后,当有新的client失效后,将会和之前的Client一起呗注销,然后被复制到server2当中
Q3:关于微服务高可用当中server失效后的处理逻辑
A3:当server1失效后,server2并不会注销server1的信息,因为这时候会开启自我保护,并不会移除这两个服务,关闭自我保护后,90秒后将会移除失效的server,此时的client1作为孤立的client,只能访问自己缓存中的服务
Q4:Eureka如何实现真正的容灾
A4:为了保证即使server挂掉了也不会影响client,我们需要所有的server之间进行互相注册,在clent中,需要注册所有的服务,从而实现server和client的高可用
如果在Eureka Server的首页看到以下这段提示,则说明Eureka已经进入了保护模式。