1.1. 一、断路器的作用。

断路器的作用是当某个服务的某个实例异常了(服务实例挂了,反应慢等),调用这个服务的客户端就会执行后备的断路器方法。 避免整个服务不可用。

例如:在双11的时候,推荐服务反应很慢,导致查询推荐很慢。因为推荐服务不是最核心的服务,调用推荐服务的client端可以返回预留的推荐商品。从而避免整个服务卡在推荐服务上。

client端使用断路器hystrix的时候,服务提供方实例如果一个特别慢(10秒返回),一个特别快(立即返回)。如果hystrix调用端设置超时时间是3秒。 如果落到特别慢的服务实例也会出现断路。会执行断路的逻辑。

1.2. 二、使用hystrix。

1.2.1. 2.1、user-provider 服务端代码。

服务端就只有一个/test/add 接口。把服务注册到注册中心即可。

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/add")
    public int add(int a,int b) {
        try {
            TimeUnit.SECONDS.sleep(10);
            System.out.println("add 执行完成 。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return a + b;
    }

}

1.2.2. 2.2、客户端。

2.2.1、依赖配置。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</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-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

使用了openfeignhystrix

2.2.2、配置文件。

application.yml配置如下:

server:
  port: 9002
spring:
  application:
    name: user-consumer-hystrix
  cloud:
    loadbalancer:
      retry:
        # 默认就是false
        enabled: false
#  datasource:
#    driverClassName: com.mysql.jdbc.Driver
#    url: jdbc:mysql://localhost:3306/user-consumer?serverTimezone=GMT%2b8
#    username: root
#    password: 123456
eureka:
  client:
    serviceUrl:
      # 注册中心的地址
      defaultZone: http://localhost:9999/eureka/
  instance:
    preferIpAddress: true
    instanceId: ${spring.cloud.client.ip-address}:${server.port}
#user-provider:
#  ribbon:
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule


feign:
#  client:
#    config:
#      default:
 #在使用hystrix时,配置这个不能改变HTTP连接的readTimeout。
#        readTimeout: 1000
  hystrix:
    # 开启 hystrix
    enabled: true
ribbon:
  # 对当前实例的最大重试次数 (包含第一次请求)
  MaxAutoRetries: 0
  OkToRetryOnAllOperations: false
# 切换实例的最大重试次数(如果重试失败就切换下一个服务实例),下一个服务实例的重试次数(包含第一次请求)
  MaxAutoRetriesNextServer: 0
# 只有下面的2个配置才可以改变 http的ReadTimeout、ConnectTimeout
  ReadTimeout: 20000
  ConnectTimeout: 5000
hystrix:
  command:
    default:
      execution:
        timeout:
          # 默认开启超时机制
          enabled: true
        isolation:
          thread:
            # timeoutInMilliseconds必须大于ribbon.ReadTimeout。
            #如果ribbon重试多次,那timeoutInMilliseconds必须大于ribbon.ReadTimeout乘以重试次数
            timeoutInMilliseconds: 60000
  1. 需要设置feign.hystrix.enabled=true让Feign支持hystrix。hystrix 使用 feign来发送请求,feignribbon做负载均衡。
  2. 需要特别注意ribbon的几个参数:官方文档

    • MaxAutoRetries 重试当前实例的次数。(包含第一次请求)
    • MaxAutoRetriesNextServer 重试下一个服务器的次数。(包含第一个实例)
    • OkToRetryOnAllOperations 对所有操作请求都进行重试。
      当访问到故障请求的时候,它会再重试访问当前实例(次数由MaxAutoRetries配置),如果不行,就换一个实例进行访问,如果还是不行,再换一次实例访问(更换实例次数由MaxAutoRetriesNextServer配置),如果依然不行,返回失败信息。
      MaxAutoRetriesMaxAutoRetriesNextServer 必须设置为0,否则在做增加、修改操作时必须是幂等的。
  3. 需要注意几个超时时间。

    • ribbon.ReadTimeoutribbon.ConnectTimeout 这2个是设置HTTP的超时时间。例如:服务提供方的某个http请求需要10秒才返回,那ribbon.ReadTimeout必须设置超过10秒。 否则会超时失败。如下图:
    • hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 这个设置hystrix的超时时间。Hystrix封装了Ribbon客户端。 timeoutInMilliseconds必须大于ribbon.ReadTimeout。如果ribbon重试多次,那timeoutInMilliseconds必须大于ribbon.ReadTimeout乘以重试次数。hystrix超时时间的计算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout。 详细查看官方文档
    • feign.client.config.default.readTimeout 这个超时时间在hystrix这里好像失效了。设置大小都无关紧要。
      springcloud官方超时重试的文档
      ribbon官方重试参数设置:
      https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties

2.2.3、启用断路器。

使用@EnableCircuitBreaker 启用断路器,使用@EnableFeignClients启用Feign

@EnableCircuitBreaker
@EnableFeignClients
@SpringBootApplication
public class UserConsumerHystrixApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserConsumerHystrixApplication.class, args);
    }

}

2.2.4、调用服务。

/**
 *调用user-provider 服务。
 */
@FeignClient(name = "user-provider",fallback = UserProviderClientFallback.class)
public interface UserProviderClient {

//    @HystrixCommand(fallbackMethod = "defaultAdd")
    // 请求/test/add 接口
    @GetMapping("/test/add")
    int add(@RequestParam(name = "a") int a, @RequestParam(name = "b") int b);
}
/**
 *UserProviderClient的断路器,后备执行逻辑。(服务降级)
 */
@Component
public class UserProviderClientFallback implements UserProviderClient{
    @Override
    public int add(int a, int b) {
        System.out.println("UserProviderClient add 出问题了。。");
        return a + b + 10000;
    }
}

使用@FeignClient注解声明了要调用name = "user-provider"的服务, 并且调用服务user-provider出问题之后执行的后备逻辑是UserProviderClientFallback.class里面对应的方法。

2.2.5、测试代码。

@RestController
@RequestMapping("/test")
public class TestHystrixController {

    @Autowired
    private UserProviderClient userProviderClient;

    @GetMapping("/hystrix/callAdd")
    public int callAdd() {
        return userProviderClient.add(3,8);
    }
}

访问 http://localhost:9002/test/hystrix/callAdd 可以看到返回了10011。证明执行了后备逻辑。 实际上就是user-consumer-hystrix服务调用user-provider服务,user-provider要10秒才返回,hystrix设置了3秒超时。所以执行了后备逻辑。 注意请求已经到达了user-provideruser-provider还是会执行完自己的add方法。

1.3. 实际使用。

在fallback函数中,可以异步发送短信通知开发人员。如果是下单失败,可以短信通知客户下单失败。

1.4. 文档。

springcloud-hystrix官方文档
官方文档:获取fallback原因
官方文档:多个bean注入报错的问题

1.5. Hystrix停止开发了。

Hystrix官网上说了Hystrix已经停止开发了, 目前是在维护中,还能使用。替代产品有以下几个:参考博客

results matching ""

    No results matching ""