springboot自定義健康檢測器
阿新 • • 發佈:2018-12-06
分散式服務註冊中心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客戶端: