Spring WebFlux

反应式系统介绍

Spring | Reactive

 官网的描述如下:

反应式系统具有某些特性,使其成为低延迟、高吞吐量工作负载的理想选择。Project Reactor 和 Spring 产品组合协同工作 ,使开发人员能够构建响应式、弹性、弹性和消息驱动的企业级响应式系统。

反应式处理是一种范例,它使开发人员能够构建可以处理背压(流控制)的非阻塞异步应用程序

反应式系统更好地利用现代处理器。此外,在响应式编程中包含背压可确保解耦组件之间更好的弹性

背压 

背压是指数据的生产者和消费者之间的一种协调机制,当数据的生产者生产数据的速度大于消费者消费数据的速度时,就会出现背压。react streams的背压协议规定了当订阅者无法处理数据时,发布者应该暂停数据的发布。
当订阅者可以处理数据时,发布者应该继续发布数据。这样就可以保证数据的生产者和消费者之间的速度一致,避免数据的丢失。

reactive Stream 规范 

Reactive Stream (响应式流/反应流) 是JDK9引入的一套标准,是一套基于发布/订阅模式的数据处理规范

react streams的核心是Publisher, Subscriber, Subscription, Processor

// 接口定义了连接发布者和订阅者的方法   
 Subscription 
// 接口定义了发布者的方法
 Publisher<T> 
// 接口定义了订阅者的方法
 Subscriber<T> 
// 接口定义了处理器
 Processor<T,R> 
  • 发布者Publisher:发布元素到订阅者
  • 订阅者Subscriber:消费元素
  • 订阅Subscription:在发布者中,订阅被创建时,将与订阅者共享
  • 处理器Processor:发布者与订阅者之间处理数据

JDK9中Reactive Stream的实现规范 通常被称为 Flow API ,通过java.util.concurrent.Flow 和java.util.concurrent.SubmissionPublisher 类来实现响应式流 

发布者

public interface Publisher<T> {
    void subscribe(Subscriber<? super T> s);
}

订阅者 

public interface Subscriber<T> {
    void onSubscribe(Subscription s);
    void onNext(T t);
    void onError(Throwable t);
    void onComplete();
}

其中的onSubscribe方法,是当订阅者订阅发布者后,发布者会调用订阅者的onSubscribe方法,将订阅者的订阅对象传递给订阅者。
其中的onNext方法,是当发布者发布数据后,会调用订阅者的onNext方法,将数据传递给订阅者。
其中的onError方法,是当发布者发布数据出现异常后,会调用订阅者的onError方法,将异常传递给订阅者。
其中的onComplete方法,是当发布者发布数据完成后,会调用订阅者的onComplete方法,通知订阅者数据发布完成。

订阅

public interface Subscription {
    void request(long n);
    void cancel();
}

Subscription是一个订阅,它负责订阅发布者的数据,订阅者可以订阅多个发布者。
其中的request方法中的n参数,是订阅者请求发布者发布数据的数量。
其中的cancel方法,是方便订阅者取消订阅发布者的数据。

processor

public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}

webFlux

webFlux的底层实现基于Netty作为网络通信,spring cloud gateway基于spring webFlux,webFlux是基于reactive Stream规范实现的project reactor 反应式编程框架的web反应式编程框架

看官网的描述:

Project Reactor是一个完全无阻塞的基础,包括背压支撑。它是Spring生态系统中反应式堆栈的基础,并在Spring WebFlux,Spring Data和Spring Cloud Gateway等项目中都有特色。

开发人员从阻塞代码转向非阻塞代码的主要原因之一是效率。反应式代码用更少的资源完成更多的工作。Project Reactor 和 Spring WebFlux 使开发人员能够利用多核下一代处理器,处理潜在的大量并发连接。通过反应式处理,您可以用更少的微服务实例满足更多的并发用户

 webFlux的基准

可以看出spring WebFlux对标的是spring MVC 他们一个基于反应式框架,一个基于servlet 

 webFlux重要类

Flux和Mono这两个 Project Reactor 的核心类:

  • Mono:实现发布者 Publisher,并返回 0 或 1 个元素。
  • Flux:实现发布者 Publisher,并返回 N 个元素

Flux

//可以指定序列中包含的全部元素。创建出来的 Flux 序列在发布这些元素之后会自动结束。
just

// 可以从一个数组、Iterable 对象或 Stream 对象中创建 Flux 对象。
fromArray(),fromIterable()和 fromStream()

// 创建一个不包含任何元素,只发布结束消息的序列,在响应式编程中,流的传递是基于元素的,empty表示没有任何元素,所以不会进行后续传递,需要用switchIfEmpty等处理
empty()

// 创建一个只包含错误消息的序列
error(Throwable error)

// 创建一个不包含任何消息通知的序列
never()

//创建包含从 start 起始的 count 个数量的 Integer 对象的序列
range(int start, int count)

Mono

// 创建对象
just
// 创建一个不包含任何元素,只发布结束消息的序列
empty
// 抛出异常
error()

 Mono.defer(()->{
     return Mono.error(new RuntimeException());
}).subscribe();

webFlux的使用

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
@RestController
public class HelloController {
    @GetMapping("/hello")
    public Mono<String> hello() {
        long start = System.currentTimeMillis();
        Mono<String> hello = Mono.fromSupplier(() -> getHelloStr());
        System.out.println("接口耗时:" + (System.currentTimeMillis() - start));
        return hello;
    }

    private String getHelloStr() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "hello";
    }
}

在 WebFlux 接口中,请求不会被阻塞,所以服务端的接口耗时为 0。

public class TestReactor {
    public static void main(String[] args) {
        //just():创建Flux序列,并声明数据流,
        Flux<Integer> integerFlux = Flux.just(1, 2, 3, 4);//整形
        //subscribe():订阅Flux序列,只有进行订阅后才回触发数据流,不订阅就什么都不会发生
        integerFlux.subscribe(System.out::println);
        
        Flux<String> stringFlux = Flux.just("hello", "world");//字符串
        stringFlux.subscribe(System.out::println);
        
        //fromArray(),fromIterable()和fromStream():可以从一个数组、Iterable 对象或Stream 对象中创建Flux序列
        Integer[] array = {1,2,3,4};
        Flux.fromArray(array).subscribe(System.out::println);
        
        List<Integer> integers = Arrays.asList(array);
        Flux.fromIterable(integers).subscribe(System.out::println);
        
        Stream<Integer> stream = integers.stream();
        Flux.fromStream(stream).subscribe(System.out::println);
    }
}

更多webFlux请移步传送门 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值