分布式服务注册中心eureka。单应用注册到eureka时候。会展示列表的应用状态。如下图:
正常情况下。会显示UP。表明当前应用是正常启动状态。但是在实际场景中。可能该应用是正常的。但是数据库服务器已经不能正常对外提供服务。导致该应用对外也是不可用的。这个时候eureka是无法将应用状态修改为DOWN.也就无法将应用剔除。这个时候我们可以自定义应用健康监测器。对应用进行自检。如果应用对用的数据库不能使用。则将应用本身设置为DOWN状态。
eureka注册中心默认通过配置:instance-info-replication-interval-seconds: 30.默认是30s。每30s判断实例的活动状态。
如下自定义监测器:
1:添加健康监测依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2:编写判断逻辑访问数据库。根据实际情况返回数据的状态
package com.itmuch.cloud.microserviceprovideruser.controller;
import com.itmuch.cloud.microserviceprovideruser.dao.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.jws.Oneway;
import java.awt.*;
/**
* : 描述信息
*
* @author liyy
* @date 2018-12-06 10:59
*/
@Controller
public class HealthController {
public static boolean flag = false;
@Autowired
private UserRepository userRepository;
@RequestMapping(value="/checkHealthStatus",method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String checkHealthStatus(){
try{
int result = userRepository.checkDbStatus();
this.flag = true;
}catch (Exception e){
this.flag = false;
}
return "当前数据库的状态:"+flag;
}
}
3:将实际得到的数据库状态返回给eureka的健康监测器。通知其当前应用是应该up还是down调。这里用到两个接口一个
HealthIndicator和HealthCheckHandler。
public interface HealthIndicator {
Health health();
}
重写其接口方法:根据实际数据库状态返回健康指示器的状态
package com.itmuch.cloud.microserviceprovideruser.common;
import com.itmuch.cloud.microserviceprovideruser.controller.HealthController;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.context.annotation.Configuration;
/**
* 自定义健康检查器: 描述信息
*
* @author liyy
* @date 2018-12-06 10:55
*/
@Configuration
public class MyHealthIndicator implements HealthIndicator{
@Override
public Health health() {
//判断如果应用是健康的。则up。否则就为down
if(HealthController.flag){
return new Health.Builder(Status.UP).build();
}else{
return new Health.Builder(Status.DOWN).build();
}
}
}
4:将HealthIndicator健康指示器的结果返回给handler去修改部署在eureka上的应用的健康情况
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.netflix.appinfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
public interface HealthCheckHandler {
InstanceStatus getStatus(InstanceStatus var1);
}
重写其接口方法。获取实例的最终状态
package com.itmuch.cloud.microserviceprovideruser.common;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.Status;
import org.springframework.stereotype.Component;
/**
* : 描述信息
*
* @author liyy
* @date 2018-12-06 10:58
*/
@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==Status.UP){
System.out.println("数据库链接正常");
return InstanceInfo.InstanceStatus.UP;
}
System.out.println("数据库链接失败");
return InstanceInfo.InstanceStatus.DOWN;
}
}
测试:
访问:http://localhost:8081/checkHealthStatus.
但数据库关闭。这返回结果:
eureka的状态是:
启动数据库。然后再访问:
再访问:
等待10s刷新eureka客户端: