Hystrix核心篇-滑动窗口基础

前言

RxJava可能有些小伙伴没有听过是什么东西,可能是因为大家平时在做业务需求的时候对异步编程了解得比较少,而RxJava就是这么一个响应式编程框架,RxJava在安卓上面用得非常多,做安卓的朋友肯定对它很熟悉。那我这里为什么要讲这个呢?因为spring cloud中服务治理框架Hystrix中大量用到了RxJava的响应式编程,为了便于理解,这里也简单给大家介绍一下。这里介绍的版本是RxJava 1.X版本的, 而在去年的早些时候,官方便宣布,将在一段时间后不再对 RxJava 1.x 进行维护,推出了RxJava2.X版本,既然有新的,为什么不介绍新的呢?因为目前最新的Hystrix版本1.5.12中使用的RxJava是1.2版本的,而2.X版本的api改动还是比较大的,所以为了大家能更加简单的理解Hystrix,所以这里是对1.X版本的介绍。

响应式编程是什么

响应式编程是一种基于异步数据流概念的编程模式,有点类似于JAVA里面的lambda表达式,相信大家都很熟悉lambda吧。数据流,stream,大家肯定不陌生,我们可以对stream有很多操作,filter、map、reduce 等常见操作。然后响应式中的核心就是响应二字,响应什么呢?响应的是事件,event 。 而流就是一个按照时间进行排序的事件序列。RxJava里面的事件是基于观察者模式,事件流将从上往下,从订阅源传递到观察者。

RxJava中重要概念

RxJava 有四个基本概念:Observable (可观察者,即被观察者)、 Observer (观察者)、 Subscriber (订阅,是Observer的抽象实现类,本质上使用是一样的)、事件。ObservableObserver 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 ObserverObservable 就像是一个生产者,在不断的生产消息,而SubscriberObserver 就像是一个消费者,在不断的消费消息

另外, RxJava 的事件回调方法还定义了两个特殊的事件,在Hystrix中用得也非常多:onCompleted()onError()

  • onCompleted(): 事件队列完结。RxJava 不仅把每个事件单独处理,还会把它们看做一个队列。RxJava 规定,当不会再有新的 onNext() 发出时,需要触发 onCompleted() 方法作为标志。
  • onError(): 事件队列异常。在事件处理过程中出异常时,onError() 会被触发,同时队列自动终止,不允许再有事件发出。

怎么做

说了这么多概念,估计大家都是一头雾水,我们直接来些实际的,加深大家的印象理解。用多的自然而然就会了,就懂了,这里说得可能不是最全的,但是说的都是Hystrix中用得很多的一些操作符,加深大家对Hystrix的理解,看源码就会容易一些。

例子

Observable<String> producer = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                subscriber.onNext("apple");
                subscriber.onNext("orange");
                subscriber.onCompleted();
            }
        });
Subscriber<String> consumer = new Subscriber<String>() {
            @Override
            public void onNext(String s) {
                LOG.info("我收到的水果有 = {}" , s);
            }
            @Override
            public void onCompleted() {
            }
            @Override
            public void onError(Throwable e) {
            }
        };
producer.subscribe(consumer);

先来一个简单的例子给大家直观的介绍下ObservableSubscriber 做了些什么,Observable 使用了onNext方法生产了2个水果,Apple和orange ,然后调用了onCompleted方法结束了这次生产, 消费者用onnext方法收到了2个水果,所以消费者就将收到的水果打印出来了,没有做任何处理

执行结果如下:

2018-04-27 10:21:11.440 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :我收到的水果有 = apple
2018-04-27 10:21:11.440 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :我收到的水果有 = orange

然后再给大家介绍一下Hystrix中用得非常多的操作符

create

Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("item1");
            subscriber.onNext("item2");
            subscriber.onCompleted();
        }
});
//在上面的例子中已经跟大家讲过了,create就是创建一个Observable,来生产消息

from

List<String> fruitList = Arrays.asList("apple","orange");
        Observable.from(fruitList).subscribe(new Action1<String>() {
            @Override
            public void call(String fruit) {
                LOG.info("fruit = {}" , fruit);
            }
        });

上面订阅者的代码被我简化了,直接new 一个Action1, 是subscribe支持的一种订阅方式,跟Subscriber是一样的道理,只是更加简化。然后我们再用lambda表达式简化一下就是这样的了

List<String> fruitList = Arrays.asList("apple","orange");
        Observable.from(fruitList).subscribe(fruit -> LOG.info("fruit = {}" , fruit));

执行结果如下:

2018-04-27 10:30:59.030 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :fruid = apple
2018-04-27 10:30:59.030 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :fruid = orange

defer

只有当订阅者订阅才创建Observable,为每个订阅创建一个新的Observable。内部通过OnSubscribeDefer在订阅时调用Func0创建Observable

List<String> fruitList = Arrays.asList("apple","orange");
        Observable.defer(new Func0<Observable<String>>() {
            @Override
            public Observable<String> call() {
                return Observable.from(fruitList);
            }
        }).subscribe(new Action1<String>() {
            @Override
            public void call(String fruit) {
                LOG.info("defer fruit = {}" , fruit);
            }
        });

不知道大家理解了没有,每次生产消息都会生产一个新的消息生产者

执行结果如下:

2018-04-27 10:37:26.209 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :defer fruit = apple
2018-04-27 10:37:26.209 INFO  [#][#] <main> com.dzy.learn.other.NormalTest :defer fruit = orange

startWith

在生产的第一个消息前加上一个或者一些消息,看例子比较直观

 List<String> fruitList = Arrays.asList("apple","orange");
        Observable.from(fruitList)
                .startWith("before apple","before apple2")
             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值