傻瓜式SpringBoot-WebFlux入门

傻瓜式SpringBoot-WebFlux入门_第1张图片

 

再说响应式编程前先来了解下WebSocker在Spring中的支持

注解名

描述

使用场景

WebSocket

@ServerEndpoint

WebSocket使用,定义端点路径

定义在某个类上,使用ws进行请求就会找到这个端点进入这个类

@OnOpen

ws连接建立成功后进入的回调方法

@OnClose

ws连接关闭时进入的回调方法

@OnMessage

ws接收到消息进入的方法

@OnError

ws发生错误进入的方法

@EnableWebSocketMessageBroker

开启ws端点注入

为什要先说WS呢,其实在WebFlux中也是可以使用WS的

响应式编程定义

  • 灵敏的:就是可以快速响应的,只要有任何可能,系统都应该能够尽可能快地做出响应
  • 可恢复的:系统在运行中可能出现问题,但是能够有很强大的容错机制和修复机制保持响应性
  • 可伸缩的:在任何负载下,响应式编程都可以根据自身压力变化,请求少时,通过减少资源释放服务器的压力,负载大时能够通过扩展算法和软硬件的方式扩展服务能力,以经济实惠的方式实现可伸缩性
  • 消息驱动的:响应式编程存在异步消息机制,事件之间的协作是通过消息进行连接的

响应式编程提出了各种模型来满足响应式编程的理念,其中著名的有Reactor和RxJava,Spring 5就是基于它们构建WebFlux,而默认的情况下它会使用Reactor

架构流程

传统的架构

傻瓜式SpringBoot-WebFlux入门_第2张图片

在这个模型中往往是请求量大于系统最大线程数(这里记为M),假设大部分请求是比较耗时的操作,那么请求数量上来后,M条线程就不能及时地响应用户了。很显然,大量的线程就只能在请求队列中等待或者被系统所抛弃,这样对于后续的请求而言,要么新来的线程要等到旧线程运行完成后才能提供服务,要么就被系统所抛弃。这样的场景往往存在那种需要大量数据流的网站中,如视频、游戏、图片和复杂计算等的网站就常常发生这样的场景

Reactor架构

傻瓜式SpringBoot-WebFlux入门_第3张图片

首先客户端会先向服务器注册其感兴趣的事件(Event),这样客户端就订阅了对应的事件,只是订阅事件并不会给服务器发送请求。当客户端发生一些已经注册的事件时,就会触发服务器的响应。当触发服务器响应时,服务器存在一个Selector线程,这个线程只是负责轮询客户端发送过来的事件,并不处理请求,当它接收到有客户端事件时,就会找到对应的请求处理器(Request Handler),然后启用另外一条线程运行处理器。因为Selector线程只是进行轮询,并不处理复杂的业务功能,所以它可以在轮询之后对请求做实时响应,速度十分快。由于事件存在很多种,所以请求处理器也存在多个,因此还需要进行区分事件的类型,所以Selector存在一个路由的问题。当请求处理器处理业务时,结果最终也会转换为数据流(data stream)发送到客户端

WebFlux概述

在比较早期大多数Web容器都是基于阻塞机制开发的(Tomcat7之前好像也都是的),而在Servlet 3.1(包含)之后,就开始了非阻塞的规范。对于高并发网站,使用函数式的编程就显得更为直观和简易,所以它十分适合那些需要高并发和大量请求的互联网的应用,特别是那些需要高速响应而对业务逻辑要求并不十分严格的网站,如游戏、视频、新闻浏览网站等

其实个人人为是Java8函数式编程的出现启发了Spring团队进行响应式编程的想法,所以在Java8公布后不就Spring团队就在社区中对Spring5进行了响应式编程的召集

傻瓜式SpringBoot-WebFlux入门_第4张图片

对于响应式编程而言分为Router Functions、Spring WebFlux和HTTP/Reactive Streams共3层

  • Router Functions:是一个路由分发层,也就是它会根据请求的事件,决定采用什么类的什么方法处理客户端发送过来的事件请求。显然,在Reactor模式中,它就是Selector的作用
  • Spring-webflux:是一种控制层,类似Spring MVC框架的层级,它主要处理业务逻辑前进行的封装和控制数据流返回格式等
  • HTTP/Reactive Streams:是将结果转换为数据流的过程

Spring WebFlux需要的是能够支持Servlet 3.1+的容器,如Tomcat、Jetty和Undertow等,而在Java异步编程的领域,使用得最多的却是Netty,所以在SpringBoot对Spring WebFlux的starter中默认是依赖于Netty库的

WebFlux数据流

  • flux
  • mono

它们都是封装数据流的类。其中Flux是存放0~N个数据流序列,响应式框架会一个接一个地(请注意不是一次性)将它们发送到客户端;而对于Mono则是存放0~1个数据流序列,这就是它们之间的区别,而它们是可以进行相互转换的。这里还存在一个背压(Backpressure)的概念,只是这个概念只对Flux有意义。对于客户端,有时候响应能力距离服务端有很大的差距,如果在很短的时间内服务端将大量的数据流传输给客户端,那么客户端就可能被压垮。为了处理这个问题,一般会考虑使用响应式拉取,也就是将服务端的数据流划分为多个序列,一次仅发送一个数据流序列给客户端,当客户端处理完这个序列后,再给服务端发送消息,然后再拉取第二个序列进行处理,处理完后,再给服务端发送消息,以此类推,直至Flux中的0~N个数据流被完全处理,这样客户端就可以根据自己响应的速度来获取数据流

WebFlux处理流程

与Spring MVC使用DispactcherServlet不同的是Spring WebFlux使用的是WebHandler。它与DispatcherServlet有异曲同工之妙,它们十分相似,所以就不需要像DispatcherServlet那样再详细地介绍它。只是WebHandler是一个接口,为此Spring WebFlux为其提供了几个实现类,以便于在不同的场景下使用

傻瓜式SpringBoot-WebFlux入门_第5张图片

可以看到整个流程都是围绕在DispatcherHandler分发处理器

WebFlux数据源交互

Spring WebFlux只能支持Spring DataReactive,但是Spring DataReactive是需要非阻塞式的交互访问,但是我们平常操作数据库大多数都是阻塞式交互的,所以支持非阻塞式交互并且应用最广泛的可能就是MongoDB了,请注意这里不要把spring-boot-starter-web的依赖也加载进来,如果将它也加载进来,Spring只会加载Spring MVC,而非Spring WebFlux了

WebFlux开发

服务端和客户端开发

类型转换器——Converter(实现WebFluxConfigurer)

你可能感兴趣的:(后端技术,spring,webflux)