日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty和RPC框架线程模型分析

發(fā)布時間:2025/6/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty和RPC框架线程模型分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

《Netty 進(jìn)階之路》、《分布式服務(wù)框架原理與實(shí)踐》作者李林鋒深入剖析Netty和RPC框架線程模型。李林鋒已在 InfoQ 上開設(shè) Netty 專題持續(xù)出稿,感興趣的同學(xué)可以持續(xù)關(guān)注。

1. 背景

1.1 線程模型的重要性

對于RPC框架而言,影響其性能指標(biāo)的主要有三個要素:

  • I/O模型:采用的是同步BIO、還是非阻塞的NIO、以及全異步的事件驅(qū)動I/O(AIO)。

  • 協(xié)議和序列化方式:它主要影響消息的序列化、反序列化性能,以及消息的通信效率。

  • 線程模型:主要影響消息的讀取和發(fā)送效率、以及調(diào)度的性能。

  • 除了對性能有影響,在一些場景下,線程模型的變化也會影響到功能的正確性,例如Netty從3.X版本升級到4.X版本之后,重構(gòu)和優(yōu)化了線程模型。當(dāng)業(yè)務(wù)沒有意識到線程模型發(fā)生變化時,就會踩到一些性能和功能方面的坑。

    1.2 Netty和RPC框架的線程模型關(guān)系

    作為一個高性能的NIO通信框架,Netty主要關(guān)注的是I/O通信相關(guān)的線程工作策略,以及提供的用戶擴(kuò)展點(diǎn)ChannelHandler的執(zhí)行策略,示例如下:

    圖1 Netty 多線程模型

    該線程模型的工作特點(diǎn)如下:

  • 有專門一個(一組)NIO線程-Acceptor線程用于監(jiān)聽服務(wù)端,接收客戶端的TCP連接請求。

  • 網(wǎng)絡(luò)I/O操作-讀、寫等由一個NIO線程池負(fù)責(zé),線程池可以采用標(biāo)準(zhǔn)的JDK線程池實(shí)現(xiàn),它包含一個任務(wù)隊(duì)列和N個可用的線程,由這些NIO線程負(fù)責(zé)消息的讀取、解碼、編碼和發(fā)送。

  • 1個NIO線程可以同時處理N條鏈路,但是1個鏈路只對應(yīng)1個NIO線程,防止發(fā)生并發(fā)操作問題。

  • 對于RPC框架,它的線程模型會更復(fù)雜一些,除了通信相關(guān)的I/O線程模型,還包括服務(wù)接口調(diào)用、服務(wù)訂閱/發(fā)布等相關(guān)的業(yè)務(wù)側(cè)線程模型。對于基于Netty構(gòu)建的RPC框架,例如gRPC、Apache ServiceComb等,它在重用Netty線程模型的基礎(chǔ)之上,也擴(kuò)展實(shí)現(xiàn)了自己的線程模型。

    2. Netty線程模型

    2.1 線程模型的變更

    2.1.1 Netty 3.X 版本線程模型

    Netty 3.X的I/O操作線程模型比較復(fù)雜,它的處理模型包括兩部分:

  • Inbound:主要包括鏈路建立事件、鏈路激活事件、讀事件、I/O異常事件、鏈路關(guān)閉事件等。

  • Outbound:主要包括寫事件、連接事件、監(jiān)聽綁定事件、刷新事件等。

  • 我們首先分析下Inbound操作的線程模型:

    圖2 Netty 3 Inbound操作線程模型

    從上圖可以看出,Inbound操作的主要處理流程如下:

  • I/O線程(Work線程)將消息從TCP緩沖區(qū)讀取到SocketChannel的接收緩沖區(qū)中。

  • 由I/O線程負(fù)責(zé)生成相應(yīng)的事件,觸發(fā)事件向上執(zhí)行,調(diào)度到ChannelPipeline中。

  • I/O線程調(diào)度執(zhí)行ChannelPipeline中Handler鏈的對應(yīng)方法,直到業(yè)務(wù)實(shí)現(xiàn)的Last Handler。

  • Last Handler將消息封裝成Runnable,放入到業(yè)務(wù)線程池中執(zhí)行,I/O線程返回,繼續(xù)讀/寫等I/O操作。

  • 業(yè)務(wù)線程池從任務(wù)隊(duì)列中彈出消息,并發(fā)執(zhí)行業(yè)務(wù)邏輯。

  • 通過對Netty 3的Inbound操作進(jìn)行分析我們可以看出,Inbound的Handler都是由Netty的I/O Work線程負(fù)責(zé)執(zhí)行。

    下面我們繼續(xù)分析Outbound操作的線程模型:

    圖3 Netty 3 Outbound操作線程模型

    從上圖可以看出,Outbound操作的主要處理流程如下:

  • 業(yè)務(wù)線程發(fā)起Channel Write操作,發(fā)送消息。

  • Netty將寫操作封裝成寫事件,觸發(fā)事件向下傳播。

  • 寫事件被調(diào)度到ChannelPipeline中,由業(yè)務(wù)線程按照Handler Chain串行調(diào)用支持Downstream事件的Channel Handler。

  • 執(zhí)行到系統(tǒng)最后一個ChannelHandler,將編碼后的消息Push到發(fā)送隊(duì)列中,業(yè)務(wù)線程返回。

  • Netty的I/O線程從發(fā)送消息隊(duì)列中取出消息,調(diào)用SocketChannel的write方法進(jìn)行消息發(fā)送。

  • 2.1.2 Netty 4.X 版本線程模型

    相比于Netty 3.X系列版本,Netty 4.X的I/O操作線程模型比較簡答,它的原理圖如下所示:

    圖4 Netty 4 Inbound和Outbound操作線程模型

    從上圖可以看出,Outbound操作的主要處理流程如下:

  • I/O線程N(yùn)ioEventLoop從SocketChannel中讀取數(shù)據(jù)報(bào),將ByteBuf投遞到ChannelPipeline,觸發(fā)ChannelRead事件。

  • I/O線程N(yùn)ioEventLoop調(diào)用ChannelHandler鏈,直到將消息投遞到業(yè)務(wù)線程,然后I/O線程返回,繼續(xù)后續(xù)的讀寫操作。

  • 業(yè)務(wù)線程調(diào)用ChannelHandlerContext.write(Object msg)方法進(jìn)行消息發(fā)送。

  • 如果是由業(yè)務(wù)線程發(fā)起的寫操作,ChannelHandlerInvoker將發(fā)送消息封裝成Task,放入到I/O線程N(yùn)ioEventLoop的任務(wù)隊(duì)列中,由NioEventLoop在循環(huán)中統(tǒng)一調(diào)度和執(zhí)行。放入任務(wù)隊(duì)列之后,業(yè)務(wù)線程返回。

  • I/O線程N(yùn)ioEventLoop調(diào)用ChannelHandler鏈,進(jìn)行消息發(fā)送,處理Outbound事件,直到將消息放入發(fā)送隊(duì)列,然后喚醒Selector,進(jìn)而執(zhí)行寫操作。

  • 通過流程分析,我們發(fā)現(xiàn)Netty 4修改了線程模型,無論是Inbound還是Outbound操作,統(tǒng)一由I/O線程N(yùn)ioEventLoop調(diào)度執(zhí)行。

    2.1.3 新老線程模型對比

    在進(jìn)行新老版本線程模型對比之前,首先還是要熟悉下串行化設(shè)計(jì)的理念:

    我們知道當(dāng)系統(tǒng)在運(yùn)行過程中,如果頻繁的進(jìn)行線程上下文切換,會帶來額外的性能損耗。多線程并發(fā)執(zhí)行某個業(yè)務(wù)流程,業(yè)務(wù)開發(fā)者還需要時刻對線程安全保持警惕,哪些數(shù)據(jù)可能會被并發(fā)修改,如何保護(hù)?這不僅降低了開發(fā)效率,也會帶來額外的性能損耗。

    為了解決上述問題,Netty 4采用了串行化設(shè)計(jì)理念,從消息的讀取、編碼以及后續(xù)Handler的執(zhí)行,始終都由I/O線程N(yùn)ioEventLoop負(fù)責(zé),這就意外著整個流程不會進(jìn)行線程上下文的切換,數(shù)據(jù)也不會面臨被并發(fā)修改的風(fēng)險(xiǎn),對于用戶而言,甚至不需要了解Netty的線程細(xì)節(jié),這確實(shí)是個非常好的設(shè)計(jì)理念,它的工作原理圖如下:

    圖5 Netty 4的串行化設(shè)計(jì)理念

    一個NioEventLoop聚合了一個多路復(fù)用器Selector,因此可以處理成百上千的客戶端連接,Netty的處理策略是每當(dāng)有一個新的客戶端接入,則從NioEventLoop線程組中順序獲取一個可用的NioEventLoop,當(dāng)?shù)竭_(dá)數(shù)組上限之后,重新返回到0,通過這種方式,可以基本保證各個NioEventLoop的負(fù)載均衡。一個客戶端連接只注冊到一個NioEventLoop上,這樣就避免了多個I/O線程去并發(fā)操作它。

    Netty通過串行化設(shè)計(jì)理念降低了用戶的開發(fā)難度,提升了處理性能。利用線程組實(shí)現(xiàn)了多個串行化線程水平并行執(zhí)行,線程之間并沒有交集,這樣既可以充分利用多核提升并行處理能力,同時避免了線程上下文的切換和并發(fā)保護(hù)帶來的額外性能損耗。

    了解完了Netty 4的串行化設(shè)計(jì)理念之后,我們繼續(xù)看Netty 3線程模型存在的問題,總結(jié)起來,它的主要問題如下:

  • Inbound和Outbound實(shí)質(zhì)都是I/O相關(guān)的操作,它們的線程模型竟然不統(tǒng)一,這給用戶帶來了更多的學(xué)習(xí)和使用成本。

  • Outbound操作由業(yè)務(wù)線程執(zhí)行,通常業(yè)務(wù)會使用線程池并行處理業(yè)務(wù)消息,這就意味著在某一個時刻會有多個業(yè)務(wù)線程同時操作ChannelHandler,我們需要對ChannelHandler進(jìn)行并發(fā)保護(hù),通常需要加鎖。如果同步塊的范圍不當(dāng),可能會導(dǎo)致嚴(yán)重的性能瓶頸,這對開發(fā)者的技能要求非常高,降低了開發(fā)效率。

  • Outbound操作過程中,例如消息編碼異常,會產(chǎn)生Exception,它會被轉(zhuǎn)換成Inbound的Exception并通知到ChannelPipeline,這就意味著業(yè)務(wù)線程發(fā)起了Inbound操作!它打破了Inbound操作由I/O線程操作的模型,如果開發(fā)者按照Inbound操作只會由一個I/O線程執(zhí)行的約束進(jìn)行設(shè)計(jì),則會發(fā)生線程并發(fā)訪問安全問題。由于該場景只在特定異常時發(fā)生,因此錯誤非常隱蔽!一旦在生產(chǎn)環(huán)境中發(fā)生此類線程并發(fā)問題,定位難度和成本都非常大。

  • 講了這么多,似乎Netty 4 完勝 Netty 3的線程模型,其實(shí)并不盡然。在特定的場景下,Netty 3的性能可能更高,如果編碼和其它Outbound操作非常耗時,由多個業(yè)務(wù)線程并發(fā)執(zhí)行,性能肯定高于單個NioEventLoop線程。

    但是,這種性能優(yōu)勢不是不可逆轉(zhuǎn)的,如果我們修改業(yè)務(wù)代碼,將耗時的Handler操作前置,Outbound操作不做復(fù)雜業(yè)務(wù)邏輯處理,性能同樣不輸于Netty 3,但是考慮內(nèi)存池優(yōu)化、不會反復(fù)創(chuàng)建Event、不需要對Handler加鎖等Netty 4的優(yōu)化,整體性能Netty 4版本肯定會更高。

    2.2 Netty 4.X版本線程模型實(shí)踐經(jīng)驗(yàn)

    2.2.1 時間可控的簡單業(yè)務(wù)直接在I/O線程上處理

    如果業(yè)務(wù)非常簡單,執(zhí)行時間非常短,不需要與外部網(wǎng)元交互、訪問數(shù)據(jù)庫和磁盤,不需要等待其它資源,則建議直接在業(yè)務(wù)ChannelHandler中執(zhí)行,不需要再啟業(yè)務(wù)的線程或者線程池。避免線程上下文切換,也不存在線程并發(fā)問題。

    2.2.2 復(fù)雜和時間不可控業(yè)務(wù)建議投遞到后端業(yè)務(wù)線程池統(tǒng)一處理

    對于此類業(yè)務(wù),不建議直接在業(yè)務(wù)ChannelHandler中啟動線程或者線程池處理,建議將不同的業(yè)務(wù)統(tǒng)一封裝成Task,統(tǒng)一投遞到后端的業(yè)務(wù)線程池中進(jìn)行處理。

    過多的業(yè)務(wù)ChannelHandler會帶來開發(fā)效率和可維護(hù)性問題,不要把Netty當(dāng)作業(yè)務(wù)容器,對于大多數(shù)復(fù)雜的業(yè)務(wù)產(chǎn)品,仍然需要集成或者開發(fā)自己的業(yè)務(wù)容器,做好和Netty的架構(gòu)分層。

    2.2.3 業(yè)務(wù)線程避免直接操作ChannelHandler

    對于ChannelHandler,I/O線程和業(yè)務(wù)線程都可能會操作,因?yàn)闃I(yè)務(wù)通常是多線程模型,這樣就會存在多線程操作ChannelHandler。為了盡量避免多線程并發(fā)問題,建議按照Netty自身的做法,通過將操作封裝成獨(dú)立的Task由NioEventLoop統(tǒng)一執(zhí)行,而不是業(yè)務(wù)線程直接操作。

    3. gRPC線程模型

    gRPC的線程模型主要包括服務(wù)端線程模型和客戶端線程模型,其中服務(wù)端線程模型主要包括:

    • 服務(wù)端監(jiān)聽和客戶端接入線程(HTTP /2 Acceptor)。

    • 網(wǎng)絡(luò)I/O讀寫線程。

    • 服務(wù)接口調(diào)用線程。

    客戶端線程模型主要包括:

    • 客戶端連接線程(HTTP/2 Connector)。

    • 網(wǎng)絡(luò)I/O讀寫線程。

    • 接口調(diào)用線程。

    • 響應(yīng)回調(diào)通知線程。

    3.1 服務(wù)端線程模型

    gRPC服務(wù)端線程模型整體上可以分為兩大類:

    • 網(wǎng)絡(luò)通信相關(guān)的線程模型,基于Netty4.1的線程模型實(shí)現(xiàn)。

    • 服務(wù)接口調(diào)用線程模型,基于JDK線程池實(shí)現(xiàn)。

    3.1.1 服務(wù)端線程模型概述

    gRPC服務(wù)端線程模型和交互圖如下所示:

    圖6 gRPC服務(wù)端線程模型

    其中,HTTP/2服務(wù)端創(chuàng)建、HTTP/2請求消息的接入和響應(yīng)發(fā)送都由Netty負(fù)責(zé),gRPC消息的序列化和反序列化、以及應(yīng)用服務(wù)接口的調(diào)用由gRPC的SerializingExecutor線程池負(fù)責(zé)。

    3.1.2 服務(wù)調(diào)度線程模型

    gRPC服務(wù)調(diào)度線程主要職責(zé)如下:

    • 請求消息的反序列化,主要包括:HTTP/2 Header的反序列化,以及將PB(Body)反序列化為請求對象。

    • 服務(wù)接口的調(diào)用,method.invoke(非反射機(jī)制)。

    • 將響應(yīng)消息封裝成WriteQueue.QueuedCommand,寫入到Netty Channel中,同時,對響應(yīng)Header和Body對象做序列化。

    服務(wù)端調(diào)度的核心是SerializingExecutor,它同時實(shí)現(xiàn)了JDK的Executor和Runnable接口,既是一個線程池,同時也是一個Task。

    SerializingExecutor聚合了JDK的Executor,由Executor負(fù)責(zé)Runnable的執(zhí)行,代碼示例如下:

    其中,Executor默認(rèn)使用的是JDK的CachedThreadPool,在構(gòu)建ServerImpl的時候進(jìn)行初始化,代碼如下:

    當(dāng)服務(wù)端接收到客戶端HTTP/2請求消息時,由Netty的NioEventLoop線程切換到gRPC的SerializingExecutor,進(jìn)行消息的反序列化、以及服務(wù)接口的調(diào)用,代碼示例如下:

    相關(guān)的調(diào)用堆棧,示例如下:

    響應(yīng)消息的發(fā)送,由SerializingExecutor發(fā)起,將響應(yīng)消息頭和消息體序列化,然后分別封裝成SendResponseHeadersCommand和SendGrpcFrameCommand,調(diào)用Netty NioSocketChannle的write方法,發(fā)送到Netty的ChannelPipeline中,由gRPC的NettyServerHandler攔截之后,真正寫入到SocketChannel中,代碼如下所示:

    響應(yīng)消息體的發(fā)送堆棧如下所示:

    Netty I/O線程和服務(wù)調(diào)度線程的運(yùn)行分工界面以及切換點(diǎn)如下所示:

    圖7 網(wǎng)絡(luò)I/O線程和服務(wù)調(diào)度線程交互圖

    事實(shí)上,在實(shí)際服務(wù)接口調(diào)用過程中,NIO線程和服務(wù)調(diào)用線程切換次數(shù)遠(yuǎn)遠(yuǎn)超過4次,頻繁的線程切換對gRPC的性能帶來了一定的損耗。

    3.2 客戶端線程模型

    gRPC客戶端的線程主要分為三類:

  • 業(yè)務(wù)調(diào)用線程。

  • 客戶端連接和I/O讀寫線程。

  • 請求消息業(yè)務(wù)處理和響應(yīng)回調(diào)線程。

  • 3.2.1 客戶端線程模型概述

    gRPC客戶端線程模型工作原理如下圖所示(同步阻塞調(diào)用為例):

    圖8 客戶端調(diào)用線程模型

    客戶端調(diào)用主要涉及的線程包括:

    • 應(yīng)用線程,負(fù)責(zé)調(diào)用gRPC服務(wù)端并獲取響應(yīng),其中請求消息的序列化由該線程負(fù)責(zé)。

    • 客戶端負(fù)載均衡以及Netty Client創(chuàng)建,由grpc-default-executor線程池負(fù)責(zé)。

    • HTTP/2客戶端鏈路創(chuàng)建、網(wǎng)絡(luò)I/O數(shù)據(jù)的讀寫,由Netty NioEventLoop線程負(fù)責(zé)。

    • 響應(yīng)消息的反序列化由SerializingExecutor負(fù)責(zé),與服務(wù)端不同的是,客戶端使用的是ThreadlessExecutor,并非JDK線程池。

    • SerializingExecutor通過調(diào)用responseFuture的set(value),喚醒阻塞的應(yīng)用線程,完成一次RPC調(diào)用。

    3.2.2 客戶端調(diào)用線程模型

    客戶端調(diào)用線程交互流程如下所示:

    圖9 客戶端線程交互原理圖

    請求消息的發(fā)送由用戶線程發(fā)起,相關(guān)代碼示例如下:

    HTTP/2 Header的創(chuàng)建、以及請求參數(shù)反序列化為Protobuf,均由用戶線程負(fù)責(zé)完成,相關(guān)代碼示例如下:

    用戶線程將請求消息封裝成CreateStreamCommand和SendGrpcFrameCommand,發(fā)送到Netty的ChannelPipeline中,然后返回,完成線程切換。后續(xù)操作由Netty NIO線程負(fù)責(zé),相關(guān)代碼示例如下:

    客戶端響應(yīng)消息的接收,由gRPC的NettyClientHandler負(fù)責(zé),相關(guān)代碼如下所示:

    接收到HTTP/2響應(yīng)之后,Netty將消息投遞到SerializingExecutor,由SerializingExecutor的ThreadlessExecutor負(fù)責(zé)響應(yīng)的反序列化,以及responseFuture的設(shè)值,相關(guān)代碼示例如下:

    3.3 線程模型總結(jié)

    消息的序列化和反序列化均由gRPC線程負(fù)責(zé),而沒有在Netty的Handler中做CodeC,原因如下:Netty4優(yōu)化了線程模型,所有業(yè)務(wù)Handler都由Netty的I/O線程負(fù)責(zé),通過串行化的方式消除鎖競爭,原理如下所示:

    圖10 Netty4串行執(zhí)行Handler

    如果大量的Handler都在Netty I/O線程中執(zhí)行,一旦某些Handler執(zhí)行比較耗時,則可能會反向影響I/O操作的執(zhí)行,像序列化和反序列化操作,都是CPU密集型操作,更適合在業(yè)務(wù)應(yīng)用線程池中執(zhí)行,提升并發(fā)處理能力。因此,gRPC并沒有在I/O線程中做消息的序列化和反序列化。

    4. Apache ServiceComb微服務(wù)框架線程模型

    Apache ServiceComb底層通信框架基于Vert.X(Netty)構(gòu)建,它重用了Netty的EventLoop線程模型,考慮到目前同步RPC調(diào)用仍然是主流模式,因此,針對同步RPC調(diào)用,在Vert.X線程模型基礎(chǔ)之上,提供了額外的線程模型封裝。

    下面我們分別對同步和異步模式的線程模型進(jìn)行分析。

    4.1 同步模式

    核心設(shè)計(jì)理念是I/O線程(協(xié)議棧)和微服務(wù)調(diào)用線程分離,線程調(diào)度模型如下所示:

    圖11 ServiceComb內(nèi)置線程池

    同步模式下ServiceComb的線程模型特點(diǎn)如下:

  • 線程池用于執(zhí)行同步模式的業(yè)務(wù)邏輯。

  • 網(wǎng)絡(luò)收發(fā)及reactive模式的業(yè)務(wù)邏輯在Eventloop中執(zhí)行,與線程池?zé)o關(guān)。

  • 默認(rèn)所有同步方法都在一個全局內(nèi)置線程池中執(zhí)行。

  • 如果業(yè)務(wù)有特殊的需求,可以指定使用自定義的全局線程池,并且可以根據(jù)schemaId或operationId指定各自使用獨(dú)立的線程池,實(shí)現(xiàn)隔離倉的效果。

  • 基于ServiceComb定制線程池策略實(shí)現(xiàn)的微服務(wù)隔離倉效果如下所示:

    圖12 基于ServiceComb的微服務(wù)故障隔離倉

    4.2 異步模式

    ServiceComb的異步模式即純Reactive機(jī)制,它的代碼示例如下:

    public interface Intf{ CompletableFuture\u0026lt;String\u0026gt; hello(String name);}@GetMapping(path = \u0026quot;/hello/{name}\u0026quot;)public CompletableFuture\u0026lt;String\u0026gt; hello(@PathVariable(name = \u0026quot;name\u0026quot;) String name){ CompletableFuture\u0026lt;String\u0026gt; future = new CompletableFuture\u0026lt;\u0026gt;(); intf.hello(name).whenComplete((result, exception) -\u0026gt; { if (exception == null) { future.complete(\u0026quot;from remote: \u0026quot; + result); return; } future.completeExceptionally(exception); }); return future;

    與之對應(yīng)的線程調(diào)度流程如下所示:

    圖13 基于ServiceComb的Reactive線程模型

    它的特點(diǎn)總結(jié)如下:

  • 所有功能都在eventloop中執(zhí)行,并不會進(jìn)行線程切換。

  • 橙色箭頭走完后,對本線程的占用即完成了,不會阻塞等待應(yīng)答,該線程可以處理其他任務(wù)。

  • 當(dāng)收到遠(yuǎn)端應(yīng)答后,由網(wǎng)絡(luò)數(shù)據(jù)驅(qū)動開始走紅色箭頭的應(yīng)答流程。

  • 只要有任務(wù),線程就不會停止,會一直執(zhí)行任務(wù),可以充分利用cpu資源,也不會產(chǎn)生多余的線程切換,去無謂地消耗cpu。

  • 4.3.線程模型總結(jié)

    ServiceComb的同步和異步RPC調(diào)用對應(yīng)的線程模型存在差異,對于純Reactive的異步,I/O讀寫與微服務(wù)業(yè)務(wù)邏輯執(zhí)行共用同一個EventLoop線程,在一次服務(wù)端RPC調(diào)用時不存在線程切換,性能最優(yōu)。但是,這種模式也存在一些約束,例如要求微服務(wù)業(yè)務(wù)邏輯執(zhí)行過程中不能有任何可能會導(dǎo)致同步阻塞的操作,包括但不限于數(shù)據(jù)庫操作、緩存讀寫、第三方HTTP服務(wù)調(diào)用、本地I/O讀寫等(本質(zhì)就是要求全棧異步)。

    對于無法做到全棧異步的業(yè)務(wù),可以使用ServiceComb同步編程模型,同時根據(jù)不同微服務(wù)接口的重要性和優(yōu)先級,利用定制線程池策略,實(shí)現(xiàn)接口級的線程隔離。

    需要指出的是,ServiceComb根據(jù)接口定義來決定采用哪種線程模型,如果返回值是CompletableFuture,業(yè)務(wù)又沒有對接口指定額外的線程池,則默認(rèn)采用Reactive模式,即業(yè)務(wù)微服務(wù)接口由Vert.X的EventLoop線程執(zhí)行。

    5. 作者簡介

    李林鋒,10年Java NIO、平臺中間件設(shè)計(jì)和開發(fā)經(jīng)驗(yàn),精通Netty、Mina、分布式服務(wù)框架、API Gateway、PaaS等,《Netty進(jìn)階之路》、《分布式服務(wù)框架原理與實(shí)踐》作者。目前在華為終端應(yīng)用市場負(fù)責(zé)業(yè)務(wù)微服務(wù)化、云化、全球化等相關(guān)設(shè)計(jì)和開發(fā)工作。

    聯(lián)系方式:新浪微博 Nettying 微信:Nettying

    Email:neu_lilinfeng@sina.com

    總結(jié)

    以上是生活随笔為你收集整理的Netty和RPC框架线程模型分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。