App下載

探索現(xiàn)代Web開發(fā)的未來:新一代Web框架WebFlux

智慧女孩不禿頭 2023-12-12 14:42:49 瀏覽數(shù) (3189)
反饋

WebFlux是一個基于反應式編程模型的Web框架,它提供了一種處理高并發(fā)和高吞吐量的Web應用程序的解決方案。本文將介紹WebFlux的概念、反應式編程的核心API和編程模型,并探討學習WebFlux的重要性。

WebFlux是什么? 

WebFlux是Spring5添加的一個新模塊,是一個使用響應式編程和異步非阻塞的Web開發(fā)框架,它的功能和Spring MVC類似,但是它可以更好地利用多核處理器和高并發(fā)連接,提高系統(tǒng)的吞吐量和伸縮性。它完全無阻塞,支持反應流反向壓力,可在 Netty、Undertow 和 Servlet 3.1+ 容器等服務器上運行。核心是基于Reactor的相關(guān)API實現(xiàn)的。

1632195879789

什么是反應式編程?

  • 反應式一詞指的是圍繞對變化做出反應而構(gòu)建的編程模型,如網(wǎng)絡組件對 I/O 事件做出反應、用戶界面控制器對鼠標事件做出反應等。從這個意義上說,非阻塞就是反應式,因為我們現(xiàn)在的模式是在操作完成或數(shù)據(jù)可用時對通知做出反應,而不是被阻塞。 
  • 同時反應式與非阻塞反向壓力建立了聯(lián)系。在同步的命令式代碼中,阻塞調(diào)用是一種自然的反向壓力,它迫使調(diào)用者等待。而在非阻塞代碼中,控制事件的速度就變得非常重要,這樣快速的生產(chǎn)者就不會壓倒其消費者(目的地)。 
  • 反應流(Reactive Streams)是一種規(guī)范(Java 9 也采用了這種規(guī)范),它定義了異步組件與反向壓力之間的交互。例如,數(shù)據(jù)存儲庫(作為發(fā)布者)可以生成數(shù)據(jù),然后 HTTP 服務器(作為訂閱者)可以將數(shù)據(jù)寫入響應。反應流的主要目的是讓訂閱者控制發(fā)布者生成數(shù)據(jù)的快慢。

WebFlux是如何實現(xiàn)響應式編程的? 

  • WebFlux是基于Reactor庫的,Reactor是一個實現(xiàn)了響應式流規(guī)范的Java庫,它提供了Flux和Mono兩種類型的數(shù)據(jù)流,分別表示多個和單個的異步數(shù)據(jù)源。WebFlux使用Flux和Mono來處理Web請求和響應,以及與數(shù)據(jù)庫和其他服務的交互,從而實現(xiàn)了端到端的異步非阻塞的處理流程。 
  • WebFlux支持兩種編程模式,一種是基于注解的,類似于Spring MVC,使用?@Controller?和?@RequestMapping?等注解來定義控制器和路由;另一種是基于函數(shù)式的,使用?RouterFunction?和?HandlerFunction?來編寫更靈活和函數(shù)式的代碼。

WebFlux有什么優(yōu)勢和局限性? 

  • WebFlux的主要優(yōu)勢是可以提高Web應用的性能和效率,特別是在IO密集型和高并發(fā)的場景下,WebFlux可以使用更少的線程和資源來處理更多的請求,從而減少延遲和內(nèi)存占用。WebFlux也可以更好地適應微服務和云原生的架構(gòu),因為它可以更容易地實現(xiàn)服務間的異步通信和流式處理。 
  • WebFlux的主要局限性是它需要使用響應式編程的思維和技巧來編寫和理解代碼,這對于習慣了同步阻塞編程的開發(fā)者來說可能有一定的學習曲線和挑戰(zhàn)。WebFlux也需要與其他支持響應式編程的庫和框架配合使用,例如Reactor,RxJava,Spring Data Reactive等,否則可能會出現(xiàn)阻塞或不兼容的問題。

應用示例

環(huán)境配置

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

注意: 不要再引spring-boot-starter-web包,否則默認還是使用的Servlet棧 

基于注解

@RestController
@RequestMapping("/demos")
public class DemoController {

  private static final Logger logger = LoggerFactory.getLogger(DemoController.class);

  @GetMapping("/index")
  public Mono<String> index() {
    logger.info("start {}, {}", Thread.currentThread().getName(), System.currentTimeMillis()) ;
    // 這里是我們需要返回的值,在Servlet棧中直接返回具體的值,但在WebFlux中需要用Mono或Flux將數(shù)據(jù)進行包裝
    Mono<String> result = Mono.just(666) ;
    logger.info("end {}, {}", Thread.currentThread().getName(), System.currentTimeMillis()) ;
    return result;
  }
}

基于注解的方式處理返回值不一樣外其它與傳統(tǒng)的WebMVC一樣。

基于函數(shù)式

@Bean
public RouterFunction<ServerResponse> router1() {
  return RouterFunctions.route()
          .GET("/r1", request -> {
            String id = request.queryParam("id").orElse(null) ;
            if ("2".equals(id)) {
              throw new RuntimeException("Router Param id Error...") ;
            }
            return ServerResponse.ok().bodyValue("你輸入的是id = " + id) ;
          }).build() ;
}

函數(shù)式,我們只需像定義普通的bean一樣即可,返回值為?RouterFucntion<ServerResponse>?。

在 WebFlux.fn 中,HTTP 請求由 ?HandlerFunction? 處理:該函數(shù)接收 ?ServerRequest? 并返回延遲的 ?ServerResponse?(即 ?Mono<ServerResponse>?)。請求和響應對象都不可變。?HandlerFunction? 相當于基于注解的編程模型中 ?@RequestMapping? 方法的主體。

總結(jié)

WebFlux作為一種新一代的Web框架,具有響應式能力、非阻塞I/O和函數(shù)式編程風格等優(yōu)勢。它適用于需要處理高并發(fā)和高吞吐量的應用場景,并在微服務架構(gòu)和云原生應用開發(fā)中表現(xiàn)出色。然而,學習和采用WebFlux可能需要一些時間和精力,并且在遷移到WebFlux時需要考慮現(xiàn)有代碼的調(diào)整和遷移工作。因此,您應該根據(jù)您的項目需求和團隊的技術(shù)能力來決定是否值得學習和采用WebFlux。了解其特點和優(yōu)勢,并與團隊進行討論和評估,以做出明智的決策。

1698630578111788

如果你對編程知識和相關(guān)職業(yè)感興趣,歡迎訪問編程獅官網(wǎng)(http://o2fo.com/)。在編程獅,我們提供廣泛的技術(shù)教程、文章和資源,幫助你在技術(shù)領(lǐng)域不斷成長。無論你是剛剛起步還是已經(jīng)擁有多年經(jīng)驗,我們都有適合你的內(nèi)容,助你取得成功。


0 人點贊