【Spring Cloud Alibaba】Hystrix 服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路。

1 Hystrix 三种模式

Hystrix的断路器模式和后备策略模式

在这里插入图片描述
Hystrix的舱壁模式
在这里插入图片描述
可以通过为各个服务分别指定线程池
在这里插入图片描述

2 熔断使用

2.1 注解的方式

编写测试服务OrderServiceImpl ,睡眠被调用功能

package cn.flowboot.e.commerce.service.impl;

import cn.flowboot.e.commerce.service.OrderService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <h1></h1>
 *
 * @version 1.0
 * @author: Vincent Vic
 * @since: 2022/03/06
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
   

    /**
     * 订单列表
     * 测试
     * @return
     */
    @Override
    public List<Map<String, Object>> list() {
   
        Map<String, Object> map = Maps.newHashMap();
        map.put("orderNo","1234567890");
        log.info("now time : {}", LocalDateTime.now());
        try {
   
            Thread.sleep(3000);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }

        log.info("now time : {}", LocalDateTime.now());
        return Lists.newArrayList(map);
    }
}

编写用于测试熔断的的中间服务,使用@HystrixCommand 注解,

package cn.flowboot.e.commerce.hystrix;

import cn.flowboot.e.commerce.service.OrderService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <h1> 使用 HystrixCommand 注解 </h1>
 *
 * @version 1.0
 * @author: Vincent Vic
 * @since: 2022/03/06
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UseHystrixCommandAnnotation {
   

    private final OrderService orderService;


    @HystrixCommand(
            // 用于对 Hystrix 命令进行分组, 分组之后便于统计展示于仪表盘、上传报告和预警等等
            // 内部进行度量统计时候的分组标识, 数据上报和统计的最小维度就是 groupKey
            groupKey = "OrderService",
            // HystrixCommand 的名字, 默认是当前类的名字, 主要方便 Hystrix 进行监控、报警等
            commandKey = "OrderService",
            // 舱壁模式
            threadPoolKey = "OrderService",
            // 后备模式
            fallbackMethod = "listFallback",
            // 断路器模式
            commandProperties = {
   
                    // 超时时间, 单位毫秒, 超时进 fallback
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1500"),
                    // 判断熔断的最少请求数, 默认是10; 只有在一定时间内请求数量达到该值, 才会进行成功率的计算
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
                    // 熔断的阈值默认值 50, 表示在一定时间内有50%的请求处理失败, 会触发熔断
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "10"),
            },
            // 舱壁模式
            threadPoolProperties = {
   
                    @HystrixProperty(name = "coreSize", value = "30"),
                    @HystrixProperty(name = "maxQueueSize", value = "101"),
                    @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),
                    @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"),
                    // 在时间窗口中, 收集统计信息的次数; 在 1440ms 的窗口中一共统计 12 次
                    @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"),
                    // 时间窗口, 从监听到第一次失败开始计时
                    @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440")
            }
    )
    public List<Map<String,Object>> list() {
   

        log.info("use hystrix command annotation to order list: [{}]",
                Thread.currentThread().getName());
        return orderService.list();
    }

    /**
     * <h2>list的兜底策略 - Hystrix 后备模式</h2>
     * */
    public List<Map<String,Object>> listFallback() {
   

        log.warn("trigger hystrix fallback: [{}]",
                Thread.currentThread().getName());
        return Collections.emptyList();
    }
}

编写Controller测试

@Autowired
private UseHystrixCommandAnnotation useHystrixCommandAnnotation;

@GetMapping("/list")
public List<Map<String,Object>> list(){
   
    log.info("Hystrix Command test");
    return useHystrixCommandAnnotation.list();
}

由于服务中休眠3秒而熔断策略中限制在1.5s,所以请求会触发后备策略

2.2 编程的方式

OrderService 实现包装-线程池的方式

package cn.flowboot.e.commerce.hystrix;


import cn.flowboot.e.commerce.service.OrderService;
import com.netflix.hystrix.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <h1> OrderService 实现包装</h1>
 * Hystrix舱壁模式:
 * 1。线程池
 * 2.信号量 : 有限信号机
 * @version 1.0
 * @author: Vincent Vic
 * @since: 2022/03/06
 */
@Slf4j

@Service
public class OrderHystrixCommand extends HystrixCommand<List<Map<String,Object>>> {
   

    private final OrderService orderService;

    protected OrderHystrixCommand(OrderService orderService) {
   
        super(Setter.withGroupKey(
                HystrixCommandGroupKey.Factory.asKey("OrderService"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("OrderHystrixCommand"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("OrderClientPool"))
                .andCommandPropertiesDefaults(
                        HystrixCommandProperties.Setter()
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD) //线程池隔离策略
                                .withFallbackEnabled(true)
                                .withCircuitBreakerEnabled(true)
                )
        );

        //可以配置信号量隔离策略
//        Setter semaphore = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("OrderService"))
//                .andCommandKey(HystrixCommandKey.Factory.asKey("OrderHystrixCommand"))
//                .andCommandPropertiesDefaults(
//                        HystrixCommandProperties.Setter()
//                                .withCircuitBreakerRequestVolumeThreshold(10)
//                                .withCircuitBreakerSleepWindowInMilliseconds(5000)
//                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
//                );

        this.orderService = orderService;
    }

    /**
     * Implement this method with code to be executed when {@link #execute()} or {@link #queue()} are invoked.
     *
     * @return R response type
     * @throws Exception if command execution fails
     */
    @Override
    protected List<Map<String, Object>> run() throws Exception {
   
        log.info("hystrix command to Get Order List: [{}]",
                Thread.currentThread().getName());
        return orderService.list();
    }

    /**
     * If {@link #execute()} or {@link #queue()} fails in any way then this method will be invoked to provide an opportunity to return a fallback response.
     * <p>
     * This should do work that does not require network transport to produce.
     * <p>
     * In other words, this should be a static or cached result that can immediately be returned upon failure.
     * <p>
     * If network traffic is wanted for fallback (such as going to MemCache) then the fallback implementation should invoke another {@link HystrixCommand} instance that protects against that network
     * access and possibly has another level of fallback that does not involve network access.
     * <p>
     * DEFAULT BEHAVIOR: It throws UnsupportedOperationException.
     *
     * @return R or throw UnsupportedOperationException if not implemented
     */
    @Override
    protected List<Map<String, Object>> getFallback() {
   
        log.warn("trigger hystrix fallback: [{}]",
                Thread.currentThread().getName());
        return Collections.emptyList();
    }
}

测试,有四种调用方式

/**
     * <h2> executeList - 测试编程方式服务熔断<h2>
     * version: 1.0 - 2022/3/6
     * @return {@link List< Map< String, Object>> }
     */
    @GetMapping("/execute/list")
    public List<Map<String,Object>> executeList(){
   
        log.info("Hystrix Command test");
        return orderHystrixCommand.execute();
    }

    /**
     * <h2> queueList - 测试编程方式服务熔断 - 采用异步<h2>
     * version: 1.0 - 2022/3/6
     * @param
     * @return {@link List< Map< String, Object>> }
     */
    @GetMapping("/queue/list")
    public List<Map<String,Object>> queueList() throws ExecutionException, InterruptedException {
   
        log.info("queue Hystrix Command test");
        Future<List<Map<String, Object>>> future = orderHystrixCommand.queue();
        //异步执行,这里可以进行其他操作
        return future.get();
    }

    /**
     * <h2> observeList - 测试编程方式服务熔断 - 热响应调用<h2>
     * version: 1.0 - 2022/3/6
     * @param
     * @return {@link List< Map< String, Object>> }
     */
    @GetMapping("/observe/list")
    public List<Map<String,Object>> observeList() throws ExecutionException, InterruptedException {
   
        log.info("observe Hystrix Command test");
        Observable<List<Map<String, Object>>> observe = orderHystrixCommand.observe();
        //异步执行,这里可以进行其他操作
        return observe.toBlocking().single();
    }

    /**
     * <h2> toObservableList - 测试编程方式服务熔断 - 冷响应调用<h2>
     * version: 1.0 - 2022/3/6
     * @param
     * @return {@link List< Map< String, Object>> }
     */
    @GetMapping("/observe/list")
    public List<Map<String,Object>> toObservableList() throws ExecutionException, InterruptedException {
   
        log.info("toObservable Hystrix Command test");
        Observable<List
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值