SpringCloud入门(五):断路器Hystrix(Greenwich.SR2)

前面学习了Ribbon和Feign的负载均衡、超时重试。本章我们一起学习当Ribbon结合Hystrix与Feign结合Hystrix实现服务的熔断和降级。

Hystrix是什么?

在微服务架构中,微服务之间互相依赖较大,相互之间调用必不可免的会失败。但当下游服务A因为瞬时流量导致服务崩溃,其他依赖于A服务的B、C服务由于调用A服务超时耗费了大量的资源,长时间下去,B、C服务也会崩溃。Hystrix就是用来解决服务之间相互调用失败,避免产生蝴蝶效应的熔断器,以及提供降级选项。Hystrix通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供默认选项来实现这一目标,以提高系统的整体健壮性。

用来解决什么问题

用来避免由于服务之间依赖较重,出现个别服务宕机、停止服务导致大面积服务雪崩的情况。

ribbon结合hystrix

继续【服务消费者Feign(Greenwich.SR2)】来学习

pom

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

启动类加上 @EnableHystrix 注解,开启熔断器

@EnableHystrix
@SpringBootApplication
public class RibbonApplication {

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

新增getRibbonHystrix和执行回退getHystrixFall。回退方法需要和被执行回退的方法在同一个类中。

本文采用yml方式来配置Hystrix,也可以采用注解的方式来配置,但是如果有多个相同方法配置相同,代码就会冗余,请参考【 SpringCloud入门(三):服务消费者RestTemplate+Ribbon(Greenwich.SR2)

DefaultProperties

@DefaultProperties
@RestController
public class RibbonController {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * @description 降级
     * @author hero良
     * @param name
     * @return
     */
    @GetMapping("/getRibbonHystrix")
    
    @HystrixCommand(defaultFallback = "getHystrixFall")
    public String getRibbonHystrix(){
        return restTemplate.getForObject("http://provider/appController/getRibbonHystrix", String.class);
    }

    /**
     * 回退方法需要和执行它的方法在一个类中
     * @description 降级回退
     * @author hero良
     * @param
     * @return
     */
    String getHystrixFall() {
        return "我是回退方法 getRibbonHystrix";
    }

yml配置

hystrix超时 > MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries * MaxAutoRetriesNextServer) + 1,不然还在尝试连接服务提供者,而熔断超时时间已经到了,直接熔断返回,就没有任何意义了

hystrix:
  # === === === == 默认Command === === === ==
  command:
    default:
      execution:
        isolation:
          # 调用隔离方式, 默认: 采用线程隔离, ExecutionIsolationStrategy:THREAD
          strategy: THREAD
          # 调用超时时间, 默认: 5 秒
          thread:
            timeoutInMilliseconds: 8000
          # 使用信号量隔离时, 命令调用最大的并发数
          semaphore:
            maxConcurrentRequests: 10
      #使用信号量隔离时, 命令fallback调用最大的并发数
      fallback:
        isolation:
          semaphore:
            maxConcurrentRequests: 10
      # === === === == 熔断器 === === === ==
      circuitBreaker:
        # 熔断器在整个统计时间内是否开启的阀值, 默认20个请求
        requestVolumeThreshold: 8
        # 熔断器默认工作时间, 默认: 5 秒
        sleepWindowInMilliseconds: 5
        # 默认: 50%, 当出错率超过50% 后熔断器启动
        errorThresholdPercentage: 50
        # 是否强制开启熔断器阻断所有请求, 默认: false, 不开启
        forceOpen: false
        # 是否允许熔断器忽略错误, 默认false, 不开启
        forceClosed: false
  # === === === == 线程池 === === === ==
  threadpool:
    default:
      # 配置线程池大小, 默认值10个
      coreSize: 10
      # 配置队列长度, 默认-1使用SynchronousQueue,其他值则使用LinkedBlockingQueue:不可动态修改:
      maxQueueSize: -1
      # 队列拒绝的阈值,可通过修改这个变量动态修改允许排队的长度: maxQueueSize=-1时不适用:
      queueSizeRejectionThreshold: 5
      # 线程生存时间, 默认1分钟
      keepAliveTimeMinutes: 1

服务提供者

/**
     * @description Hystrix熔断降级测试
     * @author hero良
     * @param
     * @return
     */
    @GetMapping("/getRibbonHystrix")
    public String getRibbonHystrix(){
        log.debug("************接受到请求*************");
        try {
        	//这里的sleep是模拟让请求超时,因为RestTemplate的超时时间为2000,
        	//所有这里的sleep大于2000就可以
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello ,this is getRibbonHystrix";
    }

使用postman来测试,看到接口并没有返回连接超时错误(注释掉启动类上的@EnableHystrix注解试一下),而是进入了我们指定的回退方法。
在这里插入图片描述
在这里插入图片描述
接下来我们停掉服务提供者再来测试,直接进入降级回退的方法。

feign结合hystrix

Feign整合断路器Hystrix相对比较简单的,Feign默认已经自带断路器Hystrix,不需要像Ribbon整合断路器Hystrix那样需要在pom添加依赖,也不需要在启动类添加注解。但是Feign自带断路器并没有打开,需要做些额外的配置。事实上,Spring Cloud默认已为Feign整合了Hystrix,只要Hystrix在项目的classpath中,Feign默认就会用断路器包裹所有方法。

继续【服务消费者Feign(Greenwich.SR2)】来学习

yml中开启断路由

#开启hystrix
feign:
  hystrix:
    enabled: true

新增getFeignHystrix测试熔断方法

@FeignClient(value = "provider", fallbackFactory = FeignHystrix.class)
public interface FeignClientService {

    @GetMapping("/appController/getFeignHystrix")
    String getFeignHystrix();
}

fallback定义类

/**
 * 这个类不一定要和FeignClientService写在同一个类中
 * @author hero良
 * @className HystrixClientFallback
 * @description
 */
public class HystrixClientFallback implements FeignClientService {
    @Override
    public String getFeignHystrix(String name) {
        return "出错了";
    }

fallbackFactory定义类,不只重写了方法,还能捕获异常

/**
 * @author hero良
 * @className FeignHystrix
 * @description TODO
 */
@Slf4j
@Component
public class FeignHystrix implements FallbackFactory<FeignClientService> {

    @Override
    public FeignClientService create(Throwable throwable) {
    	//打印日志
        log.info("fallback; throwable was: " + throwable.getMessage());
        
        return new FeignClientService() {
            @Override
            public String getFeignHystrix(String name) {
                return "进入hystrix的getFeignHystrix";
            }
        };
    }
}

注: fallbackFactory相当于fallback的增强版,也就是说fallbackFactory的范围更广,到收集异常的边界处了。因此我们是可以利用fallbackFactory属性来打印fallback异常的。

为Feign禁用Hystrix

上面说过,在Spring Cloud中,只要Hystrix在项目的classpath中,Feign就会使用断路器包裹Feign客户端的所有方法。这样虽然方便,但是很多场景下并不需要该功能。

全局禁用Hystrix

只须在**pplication.yml** 中配置 **feign.hystrix.enabled=false** 即可

局部禁用

@Configuration
public class FeignDisableHystrixConfiguration {

    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder() {
        return Feign.builder();
    }
}

借助Feign的自定义配置,可轻松为指定名称的Feign客户端禁用Hystrix。
在想要禁用Hystrix的@FeignClient引用该配置类即可

@FeignClient(value = "provider", /**fallback = HystrixClientFallback.class**/configuration = FeignHystrixConfiguration.class, fallbackFactory = FeignHystrix.class)

Ribbon的yml配置和Feign同样适用,这里就不贴代码了…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值