Cloud Native 12 min read

Implementing Service Circuit Breaker and Fallback with Hystrix in Spring Cloud

This article explains the concepts of service circuit breaking and degradation, introduces Hystrix and its design goals, and provides step‑by‑step code examples for integrating Hystrix, Feign, and Spring Cloud components to achieve resilient microservice communication with fallback handling.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Implementing Service Circuit Breaker and Fallback with Hystrix in Spring Cloud

服务熔断

服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。

服务降级

服务降级是从整个系统的负荷情况出发和考虑的,对某些负荷会比较高的情况,为了预防某些功能(业务场景)出现负荷过载或者响应慢的情况,在其内部暂时舍弃对一些非核心的接口和数据的请求,而直接返回一个提前准备好的fallback(退路)错误处理信息。这样,虽然提供的是一个有损的服务,但却保证了整个系统的稳定性和可用性。

熔断VS降级

相同点:

目标一致 都是从可用性和可靠性出发,为了防止系统崩溃;

用户体验类似 最终都让用户体验到的是某些功能暂时不可用;

不同点:

触发原因不同 服务熔断一般是某个服务(下游服务)故障引起,而服务降级一般是从整体负荷考虑;

Hystrix简介

Hystrix:英 [hɪst'rɪks] 美 [hɪst'rɪks] ,翻译过来是“豪猪”的意思。在分布式环境中,不可避免地会出现某些依赖的服务发生故障的情况。Hystrix是这样的一个库,它通过添加容许时延和容错逻辑来帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点,阻止跨服务的级联故障,并提供了退路选项,所有这些都可以提高系统的整体弹性。

Hystrix的设计目的:

通过第三方客户端的库来为访问依赖服务时的潜在故障提供保护和控制;

防止在复杂分布式系统中出现级联故障;

快速失败和迅速恢复;

在允许的情况下,提供退路对服务进行优雅降级;

提供近实时的监控、报警和操作控制;

接下来我们演示如何使用Hystrix,eureka服务注册中心以及message-service服务提供者无需更改。

使用Hystrix

引入Hystrix依赖

在 pom.xml 文件中引入Hystrix依赖:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.0.6.RELEASE</version>
</parent>

<properties>
  <spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!-- Eureka-Client 依赖 -->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
  <!-- Feign 依赖 -->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
  <!-- Hystrix 依赖 -->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  </dependency>
</dependencies>

<dependencyManagement>
  <dependencies>
    <!-- SpringCloud 版本控制依赖 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>${spring-cloud.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

修改启动类

在MessageCenterApplication启动类上增加@EnableCircuitBreaker注解:

@EnableFeignClients
@EnableCircuitBreaker
public class MessageCenterApplication {
 
    public static void main(String[] args) {
        new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args);
    }

}

如果注解过多,可以使用 @SpringCloudApplication 代替 @SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker 等。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {}

修改Controller

为MessageCenterController中的getMsg()接口增加断路器功能:

@GetMapping("/msg/get")
@HystrixCommand(fallbackMethod = "getMsgFallback")
public Object getMsg() {
    String msg = messageService.getMsg();
    return msg;
}

public Object getMsgFallback() {
    return "祝您 2019 猪年大吉,'猪'事如意!";
}

启动Eureka、message-service(8771端口)和message-center后,访问 http://localhost:8781/api/v1/center/msg/get 能正常返回;停掉message-service后再次访问,则返回fallback信息,证明Hystrix断路器生效。

Feign结合Hystrix

以MessageService的Feign客户端为例,为其添加Hystrix断路器功能。

修改Feign客户端

@FeignClient(name = "message-service", fallback = MessageServiceFallback.class)
public interface MessageServiceClient {

    @GetMapping("/api/v1/msg/get")
    public String getMsg();

}

创建Fallback处理类

@Component
public class MessageServiceFallback implements MessageServiceClient {

    @Override
    public String getMsg() {
        System.out.println("调用消息接口失败,对其进行降级处理!");
        return "消息接口繁忙,请稍后重试!";
    }

}

修改配置

在Spring Cloud新版本中,需要在 application.yml 中开启 Feign 对 Hystrix 的支持:

feign:
  hystrix:
    enabled: true

当 message-service 不可用时,请求 http://localhost:8781/api/v1/center/msg/get 将返回 fallback 信息,后台日志会打印相应信息,表明 fallback 被成功调用。

监控Hystrix

启用健康监控

Actuator 是 Spring Boot 提供的自省和监控模块,加入 spring-boot-starter-actuator 依赖后,可通过配置暴露 hystrix.stream 接口。

<!-- Actuator 依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
management:
  endpoints:
    web:
      exposure:
        include: hystrix.stream

启用Hystrix-Dashboard

Hystrix-Dashboard 能实时展示每个断路器的健康状态。

引入Hystrix-Dashboard依赖

<!-- Hystrix Dashboard 依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>

修改启动类

@EnableFeignClients
@SpringCloudApplication
@EnableHystrixDashboard
public class MessageCenterApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(MessageCenterApplication.class).web(WebApplicationType.SERVLET).run(args);
    }

}

仪表盘界面

启动应用后,访问 http://localhost:8781/hystrix 打开 Hystrix-Dashboard,配置监控地址 http://localhost:8781/actuator/hystrix.stream 即可开始监控。

参考文章

https://github.com/netflix/hystrix/wiki https://github.com/netflix/hystrix https://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html
Microservicesfeignservice degradationSpring Cloudcircuit breakerHystrixFallback
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.