原创

透彻理解Spring Cloud系列(三一)——Hystrix基本使用

我之前讲解Hystrix时,都是使用原生的Netfilx Hystrix,但实践中我们一般不会直接使用。所以本章,我将讲解如何在Spring Cloud中使用Hystrix,Spring Cloud对Hystrix进行了封装,我之前已经讲解过了Eureka、Ribbon、Feign,事实上,Spring Cloud Netflix Hystrix既可以独立使用,也可以和Feign整合在一起,本章我会分别讲解这两种使用方式。

关于Spring Cloud Netflix Hystrix使用的更多介绍,可以参考官方文档:https://docs.spring.io/spring-cloud-netflix/docs/2.2.5.RELEASE/reference/html/#circuit-breaker-hystrix-clients。

一、独立使用

我们先来看下如何独立使用Spring Cloud Netflix Hystrix。首先需要引入spring-cloud-starter-netflix-hystrix这个maven依赖。我这里继续沿用《透彻理解Spring Cloud(二七)——Feign基本使用》中的示例。

1.1 Maven依赖

首先,在ServiceB工程中添加Maven依赖:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <groupId>com.tpvlog</groupId>
      <artifactId>serviceB</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <packaging>jar</packaging>

      <name>serviceB</name>
      <url>http://maven.apache.org</url>

      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>

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

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.tpvlog</groupId>
            <artifactId>service-a-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-eureka-client</artifactId>
            <version>2.2.5.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

1.2 启动类

启动类中需要加上@EnableCircuitBreaker@EnableHystrix注解:

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableCircuitBreaker
public class ServiceBApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceBApplication.class, args);
    }
}

@EnableHystrix注解仅仅是对@EnableCircuitBreaker注解的一个包装而已。

1.3 服务类

最后是服务类,这里用了一个@HystrixCommand注解,Spring Cloud会为我们生成一个代理类,最终方法的执行会交给代理类,fallbackMethod指定了降级逻辑:

@Service
public class SomeService {

    @HystrixCommand(fallbackMethod = "defaultStores",commandProperties = {
      @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
    })
    public Object getStores(Map<String, Object> parameters) {
        //do stuff that might fail
    }

    // 降级方法
    public Object defaultStores(Map<String, Object> parameters) {
        return /* something useful */;
    }
}

我们还可以通过注解中的commandProperties属性配置HystrixCommand的参数,比如execution.isolation.strategy表示配置资源隔离策略。

二、整合Feign

我们再来看下如何将Feign和Hystrix整合在一起。默认情况下,Hystrix的group name就是ServiceA这种服务名称,也就是说你要调用一个服务的话,那么针对每个服务就有一个线程池,然后针对服务的每个接口方法,对应有一个自动生成的HystrixCommand,CommandKey是接口类#方法名

2.1 配置文件

首先,需要在配置文件中开启Hystrix:

# To enbale Hystrix in Feign
feign:
  hystrix:
    enabled: true

# To set thread isolation to SEMAPHORE
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE

然后可以通过hystrix.command.XXX配置Hystrix的参数,我这里用了default,表示对所有HsystrixCommand生效。我们也可以用具体的服务名称替换,比如serviceA。

2.2 服务类

接着,需要在服务接口中添加fallback配置,表示降级逻辑:

@FeignClient(name = "ServiceA",fallback = ServiceAClientFallback.class)    
public interface ServiceAClient extends ServiceAInterface {
}
static class ServiceAClientFallback implements ServiceAClient {
    public String sayHello() {
        // 降级机制
    }
}

如果我们需要知道fallback异常的原因,可以使用fallbackFactory

@FeignClient(name = "ServiceA",fallbackFactory = ServiceAClientFallbackFactory.class)    
public interface ServiceAClient extends ServiceAInterface {
}
static class ServiceAClientFallbackFactory implements FallbackFactory<ServiceAClient> {
    @Override
    public ServiceAClient create(Throwable cause) {
        return new ServiceAClient() {
            @Override
            public String sayHello() {
                return "fallback; reason was: " + cause.getMessage();
            }
        };
    }
}

三、总结

本章,我讲解了Spring Cloud Netflix Hystrix的两种使用方式,事实上它们的底层原理是一样的,我后续分析源码时会详细讲解。另外,Hystrix在使用时,一般也会用它的统计仪表盘——Hystrix DashboardTurbine,我这里就不再赘述了,它们的使用都很简单,读者可以参考Spring Cloud 官方文档。

正文到此结束

感谢赞赏~

本文目录