- 前言
- 1.什么是响应式编程:
- 2.使用spring-boot-starter-webflux:
- 3.Jetty、tomcat、undertow、netty怎么区分:
- 总结
前言
现在网关都采用spring-cloud-gateway,我们看使用过程中发现编码已经采用响应式编程,直接集成了spring-boot-starter-webflux依赖,这就捎带着把响应式编程带火了一把。本文结合我的理解对响应式编程做一个总结性的介绍,希望能帮助到大家。
1.什么是响应式编程:
提到响应式编程,跟传统的编程区别可能刚开始不太好区分,其中最重要的区别就是传统的是阻塞的,响应式编程是非阻塞异步。官网介绍响应式编程:
- In computing, reactive programming is an asynchronous programming paradigm
- concerned with data streams and the propagation of change.
- This means that it becomes possible to express static (e.g. arrays) or
- dynamic (e.g. event emitters) data streams with ease via the employed
- programming language(s), and that an inferred dependency within the
- associated execution model exists, which facilitates the automatic propagation of
- the change involved with data flow.
- 在计算机领域,响应式编程是一个专注于数据流和变化传递的异步编程范式。
- 这意味着可以使用编程语言很容易地表示静态(例如数组)或动态(例如事件发射器)数据流,
- 并且在关联的执行模型中,存在着可推断的依赖关系,这个关系的存在有利于自动传播与数据流有关的更改。
在计算机领域,响应式编程是一个专注于数据流和变化传递的异步编程范式。
这意味着可以使用编程语言很容易地表示静态(例如数组)或动态(例如事件发射器)数据流,
并且在关联的执行模型中,存在着可推断的依赖关系,这个关系的存在有利于自动传播与数据流有关的更改。
可能这段话还是不好理解,但是可以着重看下数据变化,响应式编程就是基于数据变化的新的编程模式,实现异步非阻塞,就是当请求来了之后进行订阅数据的变化,后续业务处理发布变化,然后进行监听到变化,进行响应。而传统的springmvc则是创建新线程等待阻塞,知道请求完毕,释放线程的过程。
2.使用spring-boot-starter-webflux:
比较经典的图示:
从图中我们可以看到基于spring-webmvc和spring-webflux的路线和区别。其中webflux默认是使用netty的通信框架作为web容器,相比较tomcat,netty的优势不再赘述了,并发高、传输快、封装好,其中netty的零拷贝等等。我们在使用webflux的时候注意两个需要经常使用的对象Mono和Flux:
Mono | Flux |
---|---|
实现发布者,并返回 0 或 1 个元素,即单对象 | 实现发布者,并返回 N 个元素,即 List 列表对象 |
3.Jetty、tomcat、undertow、netty怎么区分:
tomcat:市场占有率仍然非常高,虽然性能上跟其他web服务器比较会有欠缺,但是因为其成熟,实践度很高。undertow和Jetty都是基于NIO实现高并发的轻量级服务器,支持servlet3.1和websocket springboot2以后增加了webflux的web容器,而webflux是基于netty的,netty是nio的,加上其零拷贝的实现,保证其性能上占据优势。
3.1 springboot中使用jetty:
- <!-- web剔除tomcat容器= -->
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.10.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- <groupId>org.springframework.boot</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <!-- 引入Jetty容器-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jetty</artifactId>
- </dependency>
3.2 springboot中使用Webflux/Netty:
- <!-- 添加spring-boot-starter-web,默认使用tomcat作为web容器 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-logging</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-tomcat</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <!-- 去除tomcat,将undertow作为容器 -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-undertow</artifactId>
- </dependency>
总结
其实Spring提供的webflux框架简化了我们操作Netty使用的复杂性,提供了Reactor Netty库,因为网关性能的要求,所有spring-cloud-gateway直接集成了webflux,使用Netty的nio的特性极大的满足了网关高并发,高性能要求的场景,个人觉得不见得响应式编程未来会遍地开发,但是网关这种特殊的场景确实比较适合响应式编程的应用。