美文网首页
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