前言
在Spring 5中的Reactive Web框架是一个包含了一套完整的服务端技术框架,这里面包括Web容器以及Web应用框架,是一套非常值得学习的技术栈。
6.1 Reactive简介
Reactive Streams 是 JVM 中面向流的库标准和规范,它包含以下特性:
- 处理可能无限数量的元素
- 按顺序处理
- 组件之间异步传递
- 强制性非阻塞背压(Backpressure)
可以说是为了方便进行异步程序开发的一种新的编程模型。经过这样简单的介绍,响应式编程这个概念还是很抽象,不过可以参考这里仔细学习一下。
在Spring官网中,提供了下图的框架图:
从这张结构图我们可以清晰地区分出基于Servlet api和Reactive各自的技术栈结构,不过在最上层,Spring都给我们封装成了我们在SpringMVC中使用的基于注解的Web层api。如果以前在使用SpringMVC的时候,Controller里面没有耦合太多Servlet api的话,那么迁移过去就是一件很轻松的事情,在新的框架上开发也和以往没有太大的区别,除非使用到了Reactive的新特性。这一点Spring做的非常棒,充分体现出了Spring框架设计的优雅。
异步框架在处理IO密集型业务上有比较突出的性能优势,因此有了这一套框架后,以后在相关的技术选型上又多了一套方案。Spring Cloud Gateway也要求必须运行在Reactive Web中。
6.2 Reactive Web框架的设计
针对Reactive框架,Spring对Server端重新进行了抽象,其中一个最底层的接口就是HttpHandler,它的定义如下:
public interface HttpHandler {
/**
* Handle the given request and write to the response.
* @param request current request
* @param response current response
* @return indicates completion of request handling
*/
Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);
}
但是真正在Web层中,它提供的抽象是WebHandler接口,它的定义如下:
public interface WebHandler {
/**
* Handle the web server exchange.
* @param exchange the current server exchange
* @return {@code Mono<Void>} to indicate when request handling is complete
*/
Mono<Void> handle(ServerWebExchange exchange);
}
两者通过HttpWebHandlerAdapter进行适配。结构如下:
比起以往我们熟悉的HttpServletRequest和HttpServletResponse这两个Servlet api,在Reactive框架中的api就再也看不到Servlet身影了。正因为如此,底层的Web容器就不一定要是Servlet容器了,所以Spring为此增加了一个新的基于Netty的内嵌Web容器。这个Web容器只是做了很简单的封装,使用了Netty原生HttpServerCodec对http请求和响应进行decode和encode。接下来的内容需要一些Netty的知识才能理解Spring的这套设计。
Spring封装了HttpServer、NettyWebServer以及NettyReactiveWebServerFactory来注入和启动整个Netty框架。整体流程大致如下:
过程稍微有些复杂,其中关键的地方就是TcpBridgeServer(TcpServer的子类)中的newHandler方法了:
@Override
public final Mono<? extends NettyContext> newHandler(BiFunction<? super NettyInbound, ? super NettyOutbound, ? extends