使用spring-boot-actuator实现 eureka server健康检测方式

默认情况下注册到eureka server的服务是通过心跳来告知自己是UP还是DOWN,并不是通过spring-boot-actuator模块的/health端点来实现的,这样其实不是很合理。

默认的心跳实现方式可以有效的检查eureka客户端进程是否正常运作,但是无法保证客户端应用能够正常提供服务。由于大多数微服务应用都会有一些其他的外部资源依赖,比如数据库,REDIS缓存等,如果我们的应用与这些外部资源无法连通的时候,实际上已经不能提供正常的对外服务了,但因为客户端心跳依然在运行,所以它还是会被服务消费者调用,而这样的调用实际上并不能获得预期的后果。

我们可以通过在eureka客户端中配置:eureka.client.healthcheck.enabled=true,就可以改变eureka server对客户端健康检测的方式,改用actuator的/health端点来检测。


我们在前面的ribbon consumer样例工程中添加一个自定义的HealthIndicator:

[java]  view plain  copy
  1. package com.example.eurekaclientconsumerribbon.health;  
  2.   
  3. import org.springframework.boot.actuate.health.Health;  
  4. import org.springframework.boot.actuate.health.HealthIndicator;  
  5. import org.springframework.stereotype.Component;  
  6.   
  7. @Component  
  8. public class MyHealthChecker implements HealthIndicator {  
  9.   
  10.   
  11.     private boolean up = true;  
  12.   
  13.     @Override  
  14.     public Health health() {  
  15.         if (up) {  
  16.             return new Health.Builder().withDetail("aaa_cnt"10//自定义监控内容  
  17.                     .withDetail("bbb_status""up").up().build();  
  18.         } else {  
  19.             return new Health.Builder().withDetail("error""client is down").down().build();  
  20.         }  
  21.   
  22.     }  
  23.   
  24.     public boolean isUp() {  
  25.         return up;  
  26.     }  
  27.   
  28.     public void setUp(boolean up) {  
  29.         this.up = up;  
  30.     }  
  31. }  


里面有一个成员变量up,用来控制是否监控,下面我们会在请求中改变这个变量的值来模拟健康状态UP->DOWN

[java]  view plain  copy
  1. package com.example.eurekaclientconsumerribbon.controller;  
  2.   
  3. import com.example.eurekaclientconsumerribbon.health.MyHealthChecker;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.web.bind.annotation.RequestMapping;  
  6. import org.springframework.web.bind.annotation.RequestParam;  
  7. import org.springframework.web.bind.annotation.RestController;  
  8.   
  9. @RestController  
  10. public class UpController {  
  11.   
  12.     @Autowired  
  13.     MyHealthChecker myHealthChecker;  
  14.   
  15.     @RequestMapping("/up")  
  16.     public String up(@RequestParam("up") Boolean up) {  
  17.         myHealthChecker.setUp(up);  
  18.   
  19.         return up.toString();  
  20.     }  
  21.   
  22.   
  23.   
  24. }  

application.yml:

[java]  view plain  copy
  1. spring:  
  2.   application:  
  3.     name: eureka-client-consumer-ribbon  
  4. management:  
  5.   security:  
  6.     enabled: false  
  7. ---  
  8. spring:  
  9.   profiles: peer1  
  10. server:  
  11.   port: 8200  
  12. eureka:  
  13.   client:  
  14.     serviceUrl:  
  15.       defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/  
  16.     healthcheck:  
  17.           enabled: true #使用health端点来代替心跳表明服务是否可用,反应到eureka server ui上服务的UP还是DOWN  
  18.   instance:  
  19.     hostname: peer1  
  20. #    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}  
  21.   
  22. ---  
  23. spring:  
  24.   profiles: peer2  
  25. server:  
  26.   port: 8201  
  27. eureka:  
  28.   client:  
  29.     serviceUrl:  
  30.       defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/  
  31.   instance:  
  32.     hostname: peer2  
  33. #    instanceId: ${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}  

主要看配置里面设置了eureka.client.healthcheck.enabled=true,这个配置属性在IDEA里面不会自动提示,我一度怀疑写错了,试过确实有效的改变了检测方式。

启动类:

[java]  view plain  copy
  1. package com.example.eurekaclientconsumerribbon;  
  2.   
  3. import org.springframework.boot.SpringApplication;  
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  5. import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;  
  6. import org.springframework.cloud.client.loadbalancer.LoadBalanced;  
  7. import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  
  8. import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;  
  9. import org.springframework.context.annotation.Bean;  
  10. import org.springframework.web.client.RestTemplate;  
  11.   
  12. @SpringBootApplication  
  13. @EnableEurekaClient  
  14. @EnableCircuitBreaker  
  15. @EnableHystrixDashboard  
  16. public class EurekaClientConsumerRibbonApplication {  
  17.   
  18.   
  19.     @LoadBalanced  
  20.     @Bean  
  21.     RestTemplate restTemplate() {  
  22.         return new RestTemplate();  
  23.     }  
  24.   
  25.   
  26.   
  27.   
  28.     public static void main(String[] args) {  
  29.         SpringApplication.run(EurekaClientConsumerRibbonApplication.class, args);  
  30.     }  
  31. }  

pom:

[java]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  4.     <modelVersion>4.0.0</modelVersion>  
  5.   
  6.     <groupId>com.example</groupId>  
  7.     <artifactId>eureka-client-consumer-ribbon</artifactId>  
  8.     <version>0.0.1-SNAPSHOT</version>  
  9.     <packaging>jar</packaging>  
  10.   
  11.     <name>eureka-client-consumer-ribbon</name>  
  12.     <description>Demo project for Spring Boot</description>  
  13.   
  14.     <parent>  
  15.         <groupId>org.springframework.boot</groupId>  
  16.         <artifactId>spring-boot-starter-parent</artifactId>  
  17.         <version>1.5.6.RELEASE</version>  
  18.         <relativePath/> <!-- lookup parent from repository -->  
  19.     </parent>  
  20.   
  21.     <properties>  
  22.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  23.         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>  
  24.         <java.version>1.8</java.version>  
  25.         <spring-cloud.version>Dalston.SR3</spring-cloud.version>  
  26.     </properties>  
  27.   
  28.     <dependencies>  
  29.         <dependency>  
  30.             <groupId>org.springframework.cloud</groupId>  
  31.             <artifactId>spring-cloud-starter-eureka</artifactId>  
  32.         </dependency>  
  33.         <dependency>  
  34.             <groupId>org.jolokia</groupId>  
  35.             <artifactId>jolokia-core</artifactId>  
  36.         </dependency>  
  37.         <dependency>  
  38.             <groupId>org.springframework.cloud</groupId>  
  39.             <artifactId>spring-cloud-starter-ribbon</artifactId>  
  40.         </dependency>  
  41.         <dependency>  
  42.             <groupId>org.springframework.cloud</groupId>  
  43.             <artifactId>spring-cloud-starter-hystrix</artifactId>  
  44.         </dependency>  
  45.         <dependency>  
  46.             <groupId>org.springframework.cloud</groupId>  
  47.             <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>  
  48.         </dependency>  
  49.         <dependency>  
  50.             <groupId>org.springframework.boot</groupId>  
  51.             <artifactId>spring-boot-starter-actuator</artifactId>  
  52.         </dependency>  
  53.         <dependency>  
  54.             <groupId>org.springframework.boot</groupId>  
  55.             <artifactId>spring-boot-starter-test</artifactId>  
  56.             <scope>test</scope>  
  57.         </dependency>  
  58.     </dependencies>  
  59.   
  60.     <dependencyManagement>  
  61.         <dependencies>  
  62.             <dependency>  
  63.                 <groupId>org.springframework.cloud</groupId>  
  64.                 <artifactId>spring-cloud-dependencies</artifactId>  
  65.                 <version>${spring-cloud.version}</version>  
  66.                 <type>pom</type>  
  67.                 <scope>import</scope>  
  68.             </dependency>  
  69.         </dependencies>  
  70.     </dependencyManagement>  
  71.   
  72.     <build>  
  73.         <plugins>  
  74.             <plugin>  
  75.                 <groupId>org.springframework.boot</groupId>  
  76.                 <artifactId>spring-boot-maven-plugin</artifactId>  
  77.                 <executions>  
  78.                     <execution>  
  79.                         <goals>  
  80.                             <goal>build-info</goal>  
  81.                         </goals>  
  82.                     </execution>  
  83.                 </executions>  
  84.             </plugin>  
  85.         </plugins>  
  86.     </build>  
  87.   
  88.   
  89. </project>  


启动该服务将会注册到eureka server中去,此时显示的应该是UP




然后我们调用一下服务:http://localhost:8200/up?up=false,将此时查看http://localhost:8200/health,整个应用的health状态变成DOWN了:


注册中心的服务状态也将变为DOWN:



我们可以试一下把application.yml中eureka.client.healthcheck.enabled=true这段配置去掉重新启动服务,然后调用服务将health变为DOWN,但是注册中心中仍然会显示该服务的status为UP!


posted @ 2018-02-08 09:48  車輪の唄  阅读(48)  评论(0编辑  收藏  举报  来源