Reactor编程
摒弃一般的for循环、while编码方式,改为事件回调机制
高并发有三宝:缓存、异步、队排好
高可用有三宝:分片、复制、选领导
非阻塞的原理:缓冲 + 回调
1、数据流:数据源头
2、变化传播:数据操作(中间操作)
3、异步编程模式:底层控制异步
响应式编程
数据流:每个元素从流的源头,开始远远不断,自己往下滚动
onNext:当某个元素到达后,我们可以定义它的处理逻辑
onComplete:处理结束
onError:异常结束
流经过运算符计算后得到一个新的流
** 弹珠图在idea中看懂很重要**
// 测试Flux
psvm(简写主函数){
// 1、多元素的流
Flux<Integer> just = Flux.just(1,2,3,4,5);
// 流不消费就没啥用, 消费:订阅
just.subscribe(e -> sout("简写打印e1=" + e));
// 一个数据流可以有很多消费者
just.subscribe(e -> sout("简写打印e2=" + e));
// 对于每个消费者来说流都是一样的, 广播模式
Flux<Long> flux = Flux.interval(Duration.ofseconds(1));//每秒产生一个从0开始的
flux.subscribe(System.out::println);
}
// 测试Mono
// Mono<Integer>:只有一个Integer
// Flux<Integer>:有很多Integer
psvm(简写主函数){
Mono<Integer> just = Mono.just(1);
just.subscribe(System.out::println);
// 链式API中,下面的操作符操作的是上一步上面的流
// 1、doOnNext:每个数据(流的数据)到达的事件触发
// 2、doOnEach:每个元素(流的数据和信号)到达的时候触发
// 事件感知:当流发生什么事的时候,触发一个回调,系统调用提前定义好的钩子函数(Hook[钩子函数])doOnXxx
Flux<Integer> flux = Flux.range(1,3)
.delayElements(Duration.onseconds(1))
.doOnComplete(()->{
sout("流结束了...");
})
.doOnError((throwable)->{
sout("流出错了..." + throwable)
})
.doOnCancel(()->{
sout("流已被取消...")
})
//。。。。。。。。。。。。。。。。。。。。
Flux.range(1,7)
.log()//日志
.filter(i -> i>3)
.map(i->"haha-" + i)
.subscribe(sout)
}
// subscirbe:订阅流,没订阅之前什么也不做
// 响应式编程:数据流 + 变化传播(操作)
psvm(){
Flux(String )flux = Flux.range(1, 10)
.map();
flux.subscirbe(); //默认订阅
flux.subscribe(v -> sout); //指定订阅规则,正常消费,只消费正常元素
flux.subscribe(
v -> sout("v = " + v), //流元素消费
throwable -> {sout("throwable" + throwable);//感知异常结束
()->sout;//感知正常结束
});//
}
// 流的生命周期钩子可以传播给订阅者
// 自定义消费者
// doOnXxx:发生这个事件的时候产生一个回调,通知(不能改变)
// onXxx:发生这个事件后执行一个动作,可以改变元素、信号
// AOP:普通通知(前置,后置,异常,返回) 环绕通知
flux.subscribe(new Basesubscriber<String>()){
// 可自定义订阅函数,并重写钩子函数@Override
}
数据流取消
消费者调用cancel()方法,在重写的时候hookOnNext()的时候添加Cancel()操作
背压(Backpressure)和请求重塑(Reshape Requests)
// 1、buffer
public void buffer() {
Flux<List<Integer>> flux = Flux.range(1, 10)
.buffer(3);//缓冲区,缓冲3个元素,消费一次最多可以拿到三个元素
}
// 2、预取
public void limit() {
Flux.range(1, 100)
.limitRate(30) //一次预取30个元素
.log()
.subscribe();
// 75% 预取策略 limitRate(100)
// 第一次抓取100个数据,如果75%的元素已经处理了,继续抓取新的 75% 元素。
}
以编程方式创建序列
// 同步环境:generate 异步环境:create
// 编程方式创建序列
// sink:接收器、水槽、用到
public void generate() {
Flux<Object> flux = Flux.generate(()->0,//初始值
(state,sink) -> {
if (state <= 10) {
sink.next(state); //把元素传出去
} else {
sink.complete(); //完成,结束信号
}
return state + 1;
});
flux.log()
.doOnError(throwable -> sout(throwable))
.subscribe();
}
// handle:自定义流中元素处理规则
public void handle(){
Flux.range(1, 10)
.handle((value,sink)->{
sout;
sink.next("张三" + value);
})
.log()
.subscribe();
}