90-Webflux響應式編程怎么去理解?
- 前言
- 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的特性極大的滿足了網關高并發,高性能要求的場景,個人覺得不見得響應式編程未來會遍地開發,但是網關這種特殊的場景確實比較適合響應式編程的應用。