美文网首页
Hystrix 熔断简单手写

Hystrix 熔断简单手写

作者: 吉他手_c156 | 来源:发表于2020-07-27 14:43 被阅读0次

    创建熔断注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface MyHystrixCommand {
    
        long timeout() default 1000;  // 超时时间默认为 1000 毫秒(一秒)
        String callBack() default "";  // 回调方法
    }
    

    创建 AOP 类

    @Aspect
    @Component
    public class MyHystrixAop {
    
        // 创建一个固定大小的线程池
        private ExecutorService executorService = Executors.newFixedThreadPool(10);
    
        // 切入点
        @Pointcut("@annotation(MyHystrixCommand)")
        public void pointCut(){}
    
        // 拦截加了  @MyHystrixCommand 的注解
        @Around("pointCut() && @annotation(myHystrixCommand)")
        public Object doPointCut(ProceedingJoinPoint joinPoint,MyHystrixCommand myHystrixCommand) throws InterruptedException, ExecutionException, TimeoutException {
    
            // 获取目标方法返回值
            Future future = executorService.submit(()->{
                // 调用目标方法
                try {
                    return joinPoint.proceed();
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
                return null;
            });
            Object result = null;
            try {
                // 在自己设置的指定时间内获取目标方法返回值
                result = future.get(myHystrixCommand.timeout(), TimeUnit.MILLISECONDS);
            } catch (InterruptedException | ExecutionException |TimeoutException e) {
                e.printStackTrace();
                // 出错结束请求
                future.cancel(true);
                if(StringUtils.isEmpty(myHystrixCommand.callBack())){
                    throw e;
                }
            }
    
            if(result == null){
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
                // 获取目标方法
                Method method = methodSignature.getMethod();
                // 获取方法参数
                Class<?>[] parameterTypes = method.getParameterTypes();
                // 获取熔断方法
                Method m = null;
                try {
                    m = joinPoint.getTarget().getClass().getMethod(myHystrixCommand.callBack(), parameterTypes);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                // 调用熔断方法
                try {
                   return m.invoke(joinPoint.getTarget(),joinPoint.getArgs());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return result;
        }
    }
    

    创建 Controller 类

    @RestController
    @RequestMapping("/hystrix/test")
    public class MyHystrixController {
    
        // 熔断注解 设置超时时间
        @MyHystrixCommand(timeout = 2000,callBack = "callBack")
        @RequestMapping("/req")
        public String getUserInfoById(String userId){
            return "请求成功";
        }
    
        /**
         * 熔断方法
         * @param userId
         * @return
         */
        public String callBack(String userId){
            return "请求熔断了...";
        }
    }
    

    正常测试,超时时间是 2000 毫秒

    image.png

    我们让 AOP 类中请求目标方法休息 3000 毫秒试试看

    image.png

    结果请求超时了,调用了熔断方法

    image.png

    相关文章

      网友评论

          本文标题:Hystrix 熔断简单手写

          本文链接:https://www.haomeiwen.com/subject/amyzlktx.html