IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Hystrix(4) -> 正文阅读

[移动开发]Hystrix(4)

以下是 HystrixCommand 的基本“Hello World”实现:

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("exampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        return "hello" + name +"!";
    }
}

使用 HystrixObservableCommand 而不是 HystrixCommand 的等效 Hello World 解决方案将涉及重写构造方法,如下所示:

public class ObCommandHelloWorld extends HystrixObservableCommand<String> {

    private final String name;

    public ObCommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("exampleGroup"));
        this.name = name;
    }

    @Override
    protected Observable<String> construct() {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try{
                    if (!subscriber.isUnsubscribed()){
                       // 一个真实的例子:像网络调用
                        subscriber.onNext("Hello");
                        subscriber.onNext(name+"!");
                        subscriber.onCompleted();
                    }
                }catch (Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.io());
    }
}

同步执行

我们可以使用 execute() 方法同步执行 HystrixCommand,如下例所示:

 CommandHelloWorld command = new CommandHelloWorld("jin shuai");
 String execute = command.execute();

对于 HystrixObservableCommand 没有简单的等价物执行,但如果我们知道此类命令产生的 Observable 必须始终只产生一个值,我们可以通过将 .toBlocking().toFuture().get() 应用于 Observable 来模仿exexute的行为。

ObCommandHelloWorld command = new ObCommandHelloWorld("js");
String s = command.observe().toBlocking().toFuture().get();

异步执行

我们可以使用 queue() 方法异步执行 HystrixCommand,如下例所示:

CommandHelloWorld command = new CommandHelloWorld("jin shuai");
Future<String> queue = command.queue();
String s = queue.get();

以下是彼此等价的:

String s1 = command.queue().get();
String s2 = command.execute();

HystrixObservableCommand 等效

对于 HystrixObservableCommand 没有简单的队列等价物,但是如果我们知道此类命令生成的 Observable 必须始终只生成一个值,我们可以通过应用 RxJava 运算符 .toBlocking().toFuture( ) 到 Observable。

反应式执行

我们还可以使用以下方法之一将 HystrixCommand 的结果作为 Observable 来观察:

  • observe() — 返回一个立即执行命令的“hot” Observable,但由于 Observable 是通过 ReplaySubject 过滤的,所以在我们有机会subscribe之前,我们不会有丢失它发出的任何项目的危险
  • toObservable() — 返回一个“cold”的 Observable,它不会执行命令并开始发送结果,直到我们订阅 Observable
Observable<String> hot = new ObCommandHelloWorld("js").observe();
Observable<String> cold = new ObCommandHelloWorld("js").toObservable();

然后通过订阅 Observable 来检索命令的值:

hot.subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println("-------"+s);
            }
        });

使用 Java 8 lambdas/closures 更紧凑; 它看起来像这样:

        hot.subscribe(s1 -> {
            System.out.println("-------"+ s1);
        });

反应式Commands

除了使用上述方法将 HystrixCommand 转换为 Observable 之外,我们还可以创建一个 HystrixObservableCommand,它是 HystrixCommand 的专用版本,用于包装 Observables。 HystrixObservableCommand 能够包装发出多个项目的 Observables,而普通的 HystrixCommands,即使转换为 Observables,也永远不会发出超过一个项目。

在这种情况下,不要用命令逻辑覆盖 run 方法(就像使用普通 HystrixCommand 一样),而是覆盖构造方法,以便它返回我们打算包装的 Observable。

要获取 HystrixObservableCommand 的 Observable 表示,请使用以下两种方法之一:

  • observe() — 返回一个立即订阅底层 Observable 的“hot” Observable,尽管因为它是通过 ReplaySubject 过滤的,所以在我们有机会订阅生成的 Observable 之前,我们不会有丢失它发出的任何项目的危险
  • toObservable() — 返回一个“cold”的 Observable,在我们订阅生成的 Observable 之前不会订阅底层的 Observable

FallBack

我们可以通过添加一个fallback方法来支持 Hystrix 命令中的优雅降级,Hystrix 将调用该方法来获取一个或多个默认值,以防主命令失败。 我们将希望为大多数可能会失败的 Hystrix 命令实现回退,但有几个例外:

  • 执行写操作的命令

? ? ? ?如果我们的 Hystrix 命令旨在执行写入操作而不是返回值(这样的命令通常可能在 HystrixCommand 的情况下返回 void 或在 HystrixObservableCommand 的情况下返回空的 Observable),那么没有多大意义 在实施fallback。 如果写入失败,我们可能希望将失败传播回调用者。

  • 批处理系统/离线计算

? ? ? ? 如果我们的 Hystrix 命令正在填充缓存、生成报告或进行任何类型的离线计算,通常更适合将错误传播回调用者,然后调用者可以稍后重试命令,而不是向调用者发送 默默降级的反应。

无论我们的命令是否有回退,所有常见的 Hystrix 状态和断路器状态/指标都会更新以指示命令失败。

在普通的 HystrixCommand 中,我们通过 getFallback() 实现来实现回退。 Hystrix 将对所有类型的故障执行此回退,例如 run() 故障、超时、线程池或信号量拒绝以及断路器短路。 以下示例包括这样的回退:

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("exampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        throw new RuntimeException("失败");
    }

    @Override
    protected String getFallback() {
        return "失败了:"+name;
    }
}

HystrixObservableCommand 等效

对于 HystrixObservableCommand,我们可以改写 resumeWithFallback 方法,以便它返回第二个 Observable,如果失败,它将从主 Observable 接管。 请注意,由于 Observable 在发出一个或多个项目后可能会失败,因此我们的fallback不应假定它将发出观察者将看到的唯一值。

在内部,Hystrix 使用 RxJava 的 onErrorResumeNext 操作符在发生错误时在主 Observable 和备用 Observable 之间无缝转换。

错误传播

除了 HystrixBadRequestException 之外,从 run() 方法抛出的所有异常都算作失败并触发 getFallback() 和断路器(circuit-breaker)逻辑。

我们可以将要抛出的异常包装在 HystrixBadRequestException 中并通过 getCause() 检索它。 HystrixBadRequestException 旨在用于报告非法参数或非系统故障等用例,这些故障不应计入故障指标并且不应触发回退(fallback)逻辑。

HystrixObservableCommand 等效
在 HystrixObservableCommand 的情况下,不可恢复的错误是通过来自结果 Observable 的 onError 通知返回的,并且通过回退到 Hystrix 通过我们实现的 resumeWithFallback 方法获得的第二个 Observable 来完成回退。

执行异常类型

Failure TypeException classException.causesubject to fallback
FailureHystrixRuntimeException底层异常(用户控制)YES
TimeoutHystrixRuntimeExceptionj.u.c.TimeoutExceptionYES
short_circuitedHystrixRuntimeExceptionj.l.TimeoutExceptionYES
thread_pool_rejectedHystrixRuntimeExceptionj.u.c.RejectedExecutionExceptionYES
semaphore_rejectedHystrixRuntimeExceptionj.l.TimeoutExceptionYES
bad_requestHystrixBadRequestException底层异常(用户控制)NO

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:02:03  更:2022-01-28 12:03:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 12:43:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码