学习总结录 学习总结录
首页
归档
分类
标签
  • Java基础
  • Java集合
  • MySQL
  • Redis
  • JVM
  • 多线程
  • 计算机网络
  • 操作系统
  • Spring
  • Kafka
  • Elasticsearch
  • Python
  • 面试专题
  • 案例实践
  • 工具使用
  • 项目搭建
  • 服务治理
  • ORM框架
  • 分布式组件
  • MiniSpring
  • 设计模式
  • 算法思想
  • 编码规范
友链
关于
GitHub (opens new window)
首页
归档
分类
标签
  • Java基础
  • Java集合
  • MySQL
  • Redis
  • JVM
  • 多线程
  • 计算机网络
  • 操作系统
  • Spring
  • Kafka
  • Elasticsearch
  • Python
  • 面试专题
  • 案例实践
  • 工具使用
  • 项目搭建
  • 服务治理
  • ORM框架
  • 分布式组件
  • MiniSpring
  • 设计模式
  • 算法思想
  • 编码规范
友链
关于
GitHub (opens new window)
  • 案例实践

  • 工具使用

  • 项目搭建

  • 服务治理

    • 服务治理-统一白名单
    • 服务治理-超时熔断
      • 一、需求背景
      • 二、方案设计
      • 三、实现方案
        • 1、自定义注解
        • 2、服务实现
        • 3、切面实现
      • 四、案例测试
        • 1、依赖引入
        • 2、控制层调用
      • 参考
    • 服务治理-调用限流
    • 服务治理-自定义拦截
  • ORM框架

  • MiniSpring

  • 案例归档
  • 服务治理
旭日
2023-04-19
目录

服务治理-超时熔断

# 一、需求背景

对于一些核心业务,是需要保证其可靠性的,比如支付系统、订单系统等。

这类核心业务存在一个特点,那就是请求量特别大,但是请求存在网络、环境等外在因素,为了不让一些长时间的业务请求拖垮我们整个业务响应,就需要超时熔断,让超过一定时间阈值的请求熔断返回。

# 二、方案设计

  • 使用自定义注解和切面技术,拦截需要被熔断保护的方法
  • 拦截到方法后,根据设置的时间阈值进行熔断处理

# 三、实现方案

# 1、自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DoHystrix {

    /**
     * 失败结果 JSON
     */
    String returnJson() default "";

    /**
     * 超时熔断时间阈值
     */
    int timeoutValue() default 0;           

}
  • @Retention(RetentionPolicy.RUNTIME):标记注解在JVM运行时可见
  • @Target(ElementType.METHOD):注解的对象为方法

# 2、服务实现

接口定义

public interface HystrixService {
    Object access(ProceedingJoinPoint point, Method method, DoHystrix doHystrix, Object[] args) throws Throwable;
}

接口实现

@Service
public class HystrixServiceImpl extends HystrixCommand<Object> implements HystrixService {

    private ProceedingJoinPoint point;
    private Method method;
    private DoHystrix doHystrix;


    public HystrixServiceImpl() {

        /*********************************************************************************************
         * 置HystrixCommand的属性
         * GroupKey:            该命令属于哪一个组,可以帮助我们更好的组织命令。
         * CommandKey:          该命令的名称
         * ThreadPoolKey:       该命令所属线程池的名称,同样配置的命令会共享同一线程池,若不配置,会默认使用GroupKey作为线程池名称。
         * CommandProperties:   该命令的一些设置,包括断路器的配置,隔离策略,降级设置,以及一些监控指标等。
         * ThreadPoolProperties:关于线程池的配置,包括线程池大小,排队队列的大小等
         *********************************************************************************************/

        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GovernGroup"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("GovernKey"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("GovernThreadPool"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10))
        );
    }


    @Override
    public Object access(ProceedingJoinPoint point, Method method, DoHystrix doHystrix, Object[] args) throws Throwable {
        this.point = point;
        this.method = method;
        this.doHystrix = doHystrix;

        // 设置熔断超时时间
        Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GovernGroup"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionTimeoutInMilliseconds(doHystrix.timeoutValue()));

        return this.execute();

    }

    @Override
    protected Object run() throws Exception {
        try {
            return point.proceed();
        } catch (Throwable throwable) {
            return null;
        }
    }

    @Override
    protected Object getFallback() {
        return JSON.parseObject(doHystrix.returnJson(), method.getReturnType());
    }

}
  • 构造函数:配置启动参数
  • access():该方法内部拿到注解信息后,设置超时熔断时间
  • run():返回正确方法调用结果
  • getFallback():熔断保护时候返回的对象信息

# 3、切面实现

@Aspect
@Component
public class DoHystrixPoint {

    @Autowired
    private HystrixServiceImpl hystrixService;

    @Pointcut("@annotation(me.xu.hystrix.annotation.DoHystrix)")
    public void aopPoint() {
    }

    @Around("aopPoint() && @annotation(doGovern)")
    public Object doRouter(ProceedingJoinPoint point, DoHystrix doGovern) throws Throwable {
        return hystrixService.access(point, getMethod(point), doGovern, point.getArgs());
    }

    private Method getMethod(JoinPoint point) throws NoSuchMethodException {
        Signature sig = point.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return point.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}

# 四、案例测试

# 1、依赖引入

        <dependency>
            <groupId>me.xu</groupId>
            <artifactId>spring-hystrix</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

# 2、控制层调用

@RestController
public class UserController {
    private Logger logger = LoggerFactory.getLogger(UserController.class);

    /**
     * 测试:http://localhost:8081/api/queryUserInfo?userId=aaa
     */
    @DoHystrix(timeoutValue = 350, returnJson = "{\"code\":\"1111\",\"info\":\"调用方法超过350毫秒,熔断返回!\"}")
    @RequestMapping(path = "/api/queryUserInfo", method = RequestMethod.GET)
    public UserInfo queryUserInfo(@RequestParam String userId) throws InterruptedException {
        logger.info("查询用户信息,userId:{}", userId);
        Thread.sleep(1000);
        return new UserInfo("wxx:" + userId, 19, "地址");
    }

}
  • 通过注解的方式,设置了超时熔断的时间350毫秒和返回的结果信息。
  • 调用方法的过程中,通过Thread.sleep(1000),让接口调用时间变成,达到时间阈值。
{"code":"1111","info":"调用方法超过350毫秒,熔断返回!","name":null,"age":null,"address":null}

# 参考

服务治理-超时熔断 (opens new window)

上次更新: 2024/06/29, 15:13:44
服务治理-统一白名单
服务治理-调用限流

← 服务治理-统一白名单 服务治理-调用限流→

最近更新
01
基础概念
10-31
02
Pytorch
10-30
03
Numpy
10-30
更多文章>
Theme by Vdoing | Copyright © 2021-2024 旭日 | 蜀ICP备2021000788号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式