1. 程式人生 > >springboot自定義健康檢測器

springboot自定義健康檢測器

分散式服務註冊中心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客戶端: