当前位置: 首页 > 知识库问答 >
问题:

Hystrix断路器,业务例外

邹开畅
2023-03-14

有一种显而易见的方法可以将业务异常包装到holder对象中,从run()方法返回它,然后将其解包装回异常并重新抛出。但它想知道是否有更干净的方法。

共有1个答案

何峰
2023-03-14

有以下解决方案。

最直接和肮脏的方法。这看起来有点奇怪,因为您必须擦除object的命令,而且有很多类型转换。

Observable<BusinessResponse> observable = new HystrixCommand<Object>() {
    @Override
    protected Object run() throws Exception {
        try {
            return doStuff(...);
        } catch (BusinessException e) {
            return e; // so Hystrix won't treat it as a failure
        }
    }
})
.observe()
.flatMap(new Func1<Object, Observable<BusinessResponse>>() {
    @Override
    public Observable<BusinessResponse> call(Object o) {
        if (o instanceof BusinessException) {
            return Observable.error((BusinessException)o);
        } else {
            return Observable.just((BusinessResponse)o);
        }
    }
});

这个apporach需要引入额外的holder类(它也可以单独用于其他目的)。

class ResultHolder<T, E extends Exception> {
    private T result;
    private E exception;

    public ResultHolder(T result) {
        this.result = result;
    }
    public ResultHolder(E exception) {
        if (exception == null) {
            throw new IllegalArgumentException("exception can not be null");
        }
        this.exception = exception;
    }

    public T get() throws E {
        if (exception != null) {
            throw exception;
        } else {
            return result;
        }
    }

    public Observable<T> observe() {
        if (exception != null) {
            return Observable.error(exception);
        } else {
            return Observable.just(result);
        }
    }

    @SuppressWarnings("unchecked")
    public static <T, E extends Exception> ResultHolder<T, E> wrap(BusinessMethod<T, E> method) {
        try {
            return new ResultHolder<>(method.call());
        } catch (Exception e) {
            return new ResultHolder<>((E)e);
        }
    }


    public static <T, E extends Exception> Observable<T> unwrap(ResultHolder<T, E> holder) {
        return holder.observe();
    }

    interface BusinessMethod<T, E extends Exception> {
        T call() throws E;
    }
}
new HystrixCommand<ResultHolder<BusinessResponse, BusinessException>>() {
    @Override
    protected ResultHolder<BusinessResponse, BusinessException> run() throws Exception {
        return ResultHolder.wrap(() -> doStuff(...));
    }
}
.observe()
.flatMap(ResultHolder::unwrap);
new HystrixCommand<BusinessResponse>() {
    @Override
    protected BusinessResponse run() throws Exception {
        try {
            return doStuff(...);
        } catch (BusinessException e) {
            throw new HystrixBadRequestException("Business exception occurred", e);
        }
    }
}
.observe()
.onErrorResumeNext(e -> {
    if (e instanceof HystrixBadRequestException) {
        e = e.getCause(); // Unwrap original BusinessException
    }
    return Observable.error(e);
})
 类似资料:
  • 应用程序可以使用Spring Cloud Netflix项目提供的Hystrix断路器将这个启动器包含在项目pom.xml:spring-cloud-starter-hystrix中。Hystrix不依赖于Netflix Discovery Client。@EnableHystrix注释应放置在配置类(通常是主类)上。那么方法可以用@HystrixCommand注释来被断路器保护。有关详细信息,请

  • 我在我的spring boot应用程序中使用Hystrix实现断路器,我的代码如下所示: 我看到每次失败时都会调用fallback()。但3次故障后电路不开。在3次失败之后,我原以为它会直接调用并跳过。但这并没有发生。有人能告诉我我在这里做错了什么吗? 谢谢,B Jagan 下面是实际代码。我用这个玩得更远了。当我在RegistrationHystrix.RegisterSeller()方法中直接

  • Hystrix的主要优点之一是它收集关于每个HystrixCommand的一套指标。Hystrix仪表板以有效的方式显示每个断路器的运行状况。 图3. Hystrix仪表板

  • Netflix的创造了一个调用的库Hystrix实现了断路器图案。在微服务架构中,通常有多层服务调用。 图1.微服务图 较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。 图2. Hystrix回退防止级联故障 开放式电路会停止级联故障,并允许不必要的或

  • 我正在尝试春云和春靴。它使用了Netflix的OSS应用程序,其中有Ribbon和Hystrix。 Ribbon是一个负载均衡器,带有一些功能,其中一个是断路器。

  • 或者如果在我的应用程序上下文中根本不可能验证这一点? 任何输入都是有价值的。