本文準(zhǔn)備圍繞七個點來講網(wǎng)關(guān),分別是網(wǎng)關(guān)的基本概念、網(wǎng)關(guān)設(shè)計思路,、網(wǎng)關(guān)設(shè)計重點,、流量網(wǎng)關(guān)、業(yè)務(wù)網(wǎng)關(guān),、常見網(wǎng)關(guān)對比,對基礎(chǔ)概念熟悉的朋友可以根據(jù)目錄查看自己感興趣的部分,。 什么是網(wǎng)關(guān)網(wǎng)關(guān),很多地方將網(wǎng)關(guān)比如成門, 沒什么問題, 但是需要區(qū)分網(wǎng)關(guān)與網(wǎng)橋的區(qū)別, 網(wǎng)橋工作在數(shù)據(jù)鏈路層,在不同或相同類型的LAN之間存儲并轉(zhuǎn)發(fā)數(shù)據(jù)幀,,必要時進(jìn)行鏈路層上的協(xié)議轉(zhuǎn)換,。可連接兩個或多個網(wǎng)絡(luò),,在其中傳送信息包,。 網(wǎng)關(guān)是一個大概念,不具體特指一類產(chǎn)品,,只要連接兩個不同的網(wǎng)絡(luò)都可以叫網(wǎng)關(guān),網(wǎng)橋一般只轉(zhuǎn)發(fā)信息,而網(wǎng)關(guān)可能進(jìn)行包裝,。 網(wǎng)關(guān)通俗理解根據(jù)網(wǎng)關(guān)的特性,舉個例子: 假如你要去找集團(tuán)老板(這兒只是舉個例子), 大家都知道老板肯定不是誰想見就能見的, 也怕壞人嘛, 那么你去老板所在的辦公樓,假如是集團(tuán)總部, 大樓這個門就充當(dāng)了網(wǎng)關(guān)的角色, 大門一般都有看門員 ,看門員會做哪些事情呢? 首先所有想見老板的人肯定都得從這個門進(jìn)(統(tǒng)一入口), 這個門相當(dāng)于將辦公室和外界隔離了,主要為了保護(hù)里面的安全以及正常工作, 來到這個門之后, 門衛(wèi)肯定會讓你出示相關(guān)證件(鑒權(quán)檢驗), 意思就是判斷你要見老板這個請求是否合理, 如果不合理直接就拒絕了, 讓你回家等消息 , 如果鑒權(quán)之后, 發(fā)現(xiàn)你找老板其實只是為了和他談?wù)剝稍甑纳? 門衛(wèi)會跟你說這個用不著找老板, 你去集團(tuán)投資部就行了(動態(tài)路由, 將請求路由到不同的后端集群中), 此時會對你進(jìn)行一些包裝,例如給你出具一個訪問證類似的,然后告訴你路該怎么走,等等。 你看看,網(wǎng)關(guān)的作用是不是就是這三個, 最終目的就是減少你與集團(tuán)的耦合,具體到計算機(jī)上就是減少客戶端與服務(wù)端的耦合,如果沒有網(wǎng)關(guān)意味著所有請求都會直接調(diào)用服務(wù)器上的資源,這樣耦合太強(qiáng)了,服務(wù)器出了問題,客戶端會直接報錯, 例如老板換工作的地方了,如果沒有網(wǎng)關(guān)你直接去原來的地方找, 肯定會被告知老板不在這兒,。 為什么需要網(wǎng)關(guān)當(dāng)使用單體應(yīng)用程序架構(gòu)時,,客戶端(Web 或移動端)通過向后端應(yīng)用程序發(fā)起一次 REST 調(diào)用來獲取數(shù)據(jù)。負(fù)載均衡器將請求路由給 N 個相同的應(yīng)用程序?qū)嵗械囊粋€,。然后應(yīng)用程序會查詢各種數(shù)據(jù)庫表,,并將響應(yīng)返回給客戶端。微服務(wù)架構(gòu)下,,單體應(yīng)用被切割成多個微服務(wù),,如果將所有的微服務(wù)直接對外暴露,勢必會出現(xiàn)安全方面的各種問題,另外內(nèi)外耦合嚴(yán)重,。 客戶端可以直接向每個微服務(wù)發(fā)送請求,,其問題主要如下:
服務(wù)端的各個服務(wù)直接暴露給客戶端調(diào)用勢必會引起各種問題。同時,服務(wù)端的各個服務(wù)可擴(kuò)展和伸縮性很差,。API 網(wǎng)關(guān)是微服務(wù)架構(gòu)中的基礎(chǔ)組件,,位于接入層之下和業(yè)務(wù)服務(wù)層之上,如前所述的這些功能適合在 API 網(wǎng)關(guān)實現(xiàn),。 網(wǎng)關(guān)與服務(wù)器集群回到我們服務(wù)器上,下面圖介紹了網(wǎng)關(guān)(Gateway)作用,可知 Gateway 方式下的架構(gòu),,可以細(xì)到為每一個服務(wù)的實例配置一個自己的 Gateway,也可以粗到為一組服務(wù)配置一個,,甚至可以粗到為整個架構(gòu)配置一個接入的 Gateway,。于是,整個系統(tǒng)架構(gòu)的復(fù)雜度就會變得簡單可控起來,。 這張圖展示了一個多層 Gateway 架構(gòu),,其中有一個總的 Gateway 接入所有的流量(流量網(wǎng)關(guān)),并分發(fā)給不同的子系統(tǒng),,還有第二級 Gateway 用于做各個子系統(tǒng)的接入 Gateway(業(yè)務(wù)網(wǎng)關(guān)),??梢钥吹?,網(wǎng)關(guān)所管理的服務(wù)粒度可粗可細(xì)。通過網(wǎng)關(guān),,我們可以把分布式架構(gòu)組織成一個星型架構(gòu),,由網(wǎng)絡(luò)對服務(wù)的請求進(jìn)行路由和分發(fā)。下面來聊聊好的網(wǎng)關(guān)應(yīng)該具備哪些功能,也就是網(wǎng)關(guān)設(shè)計模式,。 網(wǎng)關(guān)設(shè)計思路一個網(wǎng)關(guān)需要有以下的功能: 請求路由網(wǎng)關(guān)一定要有請求路由的功能,。這樣一來,對于調(diào)用端來說,,也是一件非常方便的事情,。因為調(diào)用端不需要知道自己需要用到的其它服務(wù)的地址,全部統(tǒng)一地交給 Gateway 來處理,。 服務(wù)注冊為了能夠代理后面的服務(wù),,并把請求路由到正確的位置上,網(wǎng)關(guān)應(yīng)該有服務(wù)注冊功能,,也就是后端的服務(wù)實例可以把其提供服務(wù)的地址注冊,、取消注冊。一般來說,,注冊也就是注冊一些 API 接口,。比如,HTTP 的 Restful 請求,,可以注冊相應(yīng) API 的 URI,、方法、HTTP 頭。 這樣,,Gateway 就可以根據(jù)接收到的請求中的信息來決定路由到哪一個后端的服務(wù)上,。 負(fù)載均衡因為一個網(wǎng)關(guān)可以接收多個服務(wù)實例,所以網(wǎng)關(guān)還需要在各個對等的服務(wù)實例上做負(fù)載均衡策略,。簡單點就是直接 Round-Robin 輪詢,,復(fù)雜點的可以設(shè)置上權(quán)重進(jìn)行分發(fā),再復(fù)雜一點還可以做到 session 粘連,。 彈力設(shè)計網(wǎng)關(guān)還可以把彈力設(shè)計中的那些異步,、重試、冪等,、流控,、熔斷、監(jiān)視等都可以實現(xiàn)進(jìn)去,。這樣,,同樣可以像 Service Mesh 那樣,讓應(yīng)用服務(wù)只關(guān)心自己的業(yè)務(wù)邏輯(或是說數(shù)據(jù)面上的事)而不是控制邏輯(控制面),。 安全方面SSL 加密及證書管理,、Session 驗證、授權(quán),、數(shù)據(jù)校驗,,以及對請求源進(jìn)行惡意攻擊的防范。錯誤處理越靠前的位置就是越好,,所以,,網(wǎng)關(guān)可以做到一個全站的接入組件來對后端的服務(wù)進(jìn)行保護(hù)。當(dāng)然,,網(wǎng)關(guān)還可以做更多更有趣的事情,,比如:灰度發(fā)布、API聚合,、API編排,。 灰度發(fā)布 網(wǎng)關(guān)完全可以做到對相同服務(wù)不同版本的實例進(jìn)行導(dǎo)流,還可以收集相關(guān)的數(shù)據(jù),。這樣對于軟件質(zhì)量的提升,,甚至產(chǎn)品試錯都有非常積極的意義。 API 聚合 使用網(wǎng)關(guān)可以將多個單獨請求聚合成一個請求,。在微服務(wù)體系的架構(gòu)中,,因為服務(wù)變小了,所以一個明顯的問題是,,客戶端可能需要多次請求才能得到所有的數(shù)據(jù),。這樣一來,,客戶端與后端之間的頻繁通信會對應(yīng)用程序的性能和規(guī)模產(chǎn)生非常不利的影響。于是,,我們可以讓網(wǎng)關(guān)來幫客戶端請求多個后端的服務(wù)(有些場景下完全可以并發(fā)請求),,然后把后端服務(wù)的響應(yīng)結(jié)果拼裝起來,回傳給客戶端(當(dāng)然,,這個過程也可以做成異步的,,但這需要客戶端的配合)。 API 編排 同樣在微服務(wù)的架構(gòu)下,,要走完一個完整的業(yè)務(wù)流程,,我們需要調(diào)用一系列 API,就像一種工作流一樣,,這個事完全可以通過網(wǎng)頁來編排這個業(yè)務(wù)流程,。我們可能通過一個 DSL 來定義和編排不同的 API,也可以通過像 AWS Lambda 服務(wù)那樣的方式來串聯(lián)不同的 API,。 網(wǎng)關(guān)設(shè)計重點網(wǎng)關(guān)設(shè)計重點主要是三個, 高性能,、高可用、高擴(kuò)展: 高性能在技術(shù)設(shè)計上,,網(wǎng)關(guān)不應(yīng)該也不能成為性能的瓶頸,。對于高性能,最好使用高性能的編程語言來實現(xiàn),,如 C,、C++,、Go 和 Java,。網(wǎng)關(guān)對后端的請求,以及對前端的請求的服務(wù)一定要使用異步非阻塞的 I/O 來確保后端延遲不會導(dǎo)致應(yīng)用程序中出現(xiàn)性能問題,。C 和 C++ 可以參看 Linux 下的 epoll 和 Windows 的 I/O Completion Port 的異步 IO 模型,,Java 下如 Netty、Spring Reactor 的 NIO 框架,。 高可用因為所有的流量或調(diào)用經(jīng)過網(wǎng)關(guān),,所以網(wǎng)關(guān)必須成為一個高可用的技術(shù)組件,它的穩(wěn)定直接關(guān)系到了所有服務(wù)的穩(wěn)定,。網(wǎng)關(guān)如果沒有設(shè)計,,就會成變一個單點故障。因此,,一個好的網(wǎng)關(guān)至少要做到以下幾點,。
高擴(kuò)展因為網(wǎng)關(guān)需要承接所有的業(yè)務(wù)流量和請求,所以一定會有或多或少的業(yè)務(wù)邏輯,。而我們都知道,,業(yè)務(wù)邏輯是多變和不確定的。比如,,需要在網(wǎng)關(guān)上加入一些和業(yè)務(wù)相關(guān)的東西,。因此,一個好的 Gateway 還需要是可以擴(kuò)展的,,并能進(jìn)行二次開發(fā)的,。當(dāng)然,像 Nginx 那樣通過 Module 進(jìn)行二次開發(fā)的固然可以,。 另外,,在運維方面,網(wǎng)關(guān)應(yīng)該有以下幾個設(shè)計原則,。
網(wǎng)關(guān)設(shè)計注意事項
另外,,因為網(wǎng)關(guān)是為用戶請求和后端服務(wù)的橋接裝置,,所以需要考慮一些安全方面的事宜。具體如下:
流量網(wǎng)關(guān)流量網(wǎng)關(guān),顧名思義就是控制流量進(jìn)入集群的網(wǎng)關(guān),有很多工作需要在這一步做,對于一個服務(wù)集群,勢必有很多非法的請求或者無效的請求,這時候要將請求拒之門外,降低集群的流量壓力,。 定義全局性的、跟具體的后端業(yè)務(wù)應(yīng)用和服務(wù)完全無關(guān)的策略網(wǎng)關(guān)就是上圖所示的架構(gòu)模型——流量網(wǎng)關(guān),。流量網(wǎng)關(guān)通常只專注于全局的Api管理策略,,比如全局流量監(jiān)控、日志記錄,、全局限流,、黑白名單控制、接入請求到業(yè)務(wù)系統(tǒng)的負(fù)載均衡等,,有點類似防火墻,。Kong 就是典型的流量網(wǎng)關(guān)。 下面是kong的架構(gòu)圖,來自官網(wǎng): 這里需要補充一點的是,,業(yè)務(wù)網(wǎng)關(guān)一般部署在流量網(wǎng)關(guān)之后,、業(yè)務(wù)系統(tǒng)之前,比流量網(wǎng)關(guān)更靠近業(yè)務(wù)系統(tǒng),。通常API網(wǎng)指的是業(yè)務(wù)網(wǎng)關(guān),。 有時候我們也會模糊流量網(wǎng)關(guān)和業(yè)務(wù)網(wǎng)關(guān),讓一個網(wǎng)關(guān)承擔(dān)所有的工作,所以這兩者之間并沒有嚴(yán)格的界線,。 業(yè)務(wù)網(wǎng)關(guān)當(dāng)一個單體應(yīng)用被拆分成許許多多的微服務(wù)應(yīng)用后,也帶來了一些問題,。一些與業(yè)務(wù)非強(qiáng)相關(guān)的功能,,比如權(quán)限控制,、日志輸出、數(shù)據(jù)加密,、熔斷限流等,,每個微服務(wù)應(yīng)用都需要,因此存在著大量重復(fù)的代碼實現(xiàn),。而且由于系統(tǒng)的迭代,、人員的更替,各個微服務(wù)中這些功能的實現(xiàn)細(xì)節(jié)出現(xiàn)了較大的差異,,導(dǎo)致維護(hù)成本變高,。另一方面,原先單體應(yīng)用下非常容易做的接口管理,,在服務(wù)拆分后沒有了一個集中管理的地方,,無法統(tǒng)計已存在哪些接口、接口定義是什么,、運行狀態(tài)如何,。 網(wǎng)關(guān)就是為了解決上述問題。作為微服務(wù)體系中的核心基礎(chǔ)設(shè)施,,一般需要具備接口管理,、協(xié)議適配、熔斷限流,、安全防護(hù)等功能,,各種開源的網(wǎng)關(guān)產(chǎn)品(比如 zuul)都提供了優(yōu)秀高可擴(kuò)展性的架構(gòu)、可以很方便的實現(xiàn)我們需要的一些功能,、比如鑒權(quán),、日志監(jiān)控、熔斷限流等,。 與流量網(wǎng)關(guān)相對應(yīng)的就是業(yè)務(wù)網(wǎng)關(guān),業(yè)務(wù)網(wǎng)關(guān)更靠近我們的業(yè)務(wù),也就是與服務(wù)器應(yīng)用層打交道,那么有很多應(yīng)用層需要考慮的事情就可以依托業(yè)務(wù)網(wǎng)關(guān),例如在線程模型,、協(xié)議適配、熔斷限流,,服務(wù)編排等,。下面看看業(yè)務(wù)網(wǎng)關(guān)體系結(jié)構(gòu): 圖片來自:業(yè)務(wù)網(wǎng)關(guān)的落地實踐 從這個途中可以看出業(yè)務(wù)網(wǎng)關(guān)主要職責(zé)以及所做的事情, 目前業(yè)務(wù)網(wǎng)關(guān)比較成熟的 API 網(wǎng)關(guān)框架產(chǎn)品有三個 分別是:Zuul1、Zuul2 和 SpringCloud Gateway, 后面再進(jìn)行對比,。 常見網(wǎng)關(guān)對比既然對比,就先宏觀上對各種網(wǎng)關(guān)有一個了解,后面再挑一些常用的或者說應(yīng)用廣泛的詳細(xì)了解,。 目前常見的開源網(wǎng)關(guān)大致上按照語言分類有如下幾類:
按照使用數(shù)量、成熟度等來劃分,,主流的有 4 個:
OpenResty相關(guān)連接: 官網(wǎng),、B站、Github OpenResty是一個流量網(wǎng)關(guān),根據(jù)前面對流量網(wǎng)關(guān)的介紹就可以知道流量網(wǎng)關(guān)的指責(zé),。 OpenResty基于 Nginx 與 Lua 的高性能 Web 平臺,,其內(nèi)部集成了大量精良的 Lua 庫、第三方模塊以及大多數(shù)的依賴項,。用于方便地搭建能夠處理超高并發(fā),、擴(kuò)展性極高的動態(tài) Web 應(yīng)用、Web 服務(wù)和動態(tài)網(wǎng)關(guān),。 通過揉和眾多設(shè)計良好的 Nginx 模塊,,OpenResty 有效地把 Nginx 服務(wù)器轉(zhuǎn)變?yōu)橐粋€強(qiáng)大的 Web 應(yīng)用服務(wù)器,基于它開發(fā)人員可以使用 Lua 編程語言對 Nginx 核心以及現(xiàn)有的各種 Nginx C 模塊進(jìn)行腳本編程,,構(gòu)建出可以處理一萬以上并發(fā)請求的極端高性能的 Web 應(yīng)用 OpenResty 最早是順應(yīng) OpenAPI 的潮流做的,,所以 Open 取自“開放”之意,而Resty便是 REST 風(fēng)格的意思,。雖然后來也可以基于 ngx_openresty 實現(xiàn)任何形式的 web service 或者傳統(tǒng)的 web 應(yīng)用,。 也就是說 Nginx 不再是一個簡單的靜態(tài)網(wǎng)頁服務(wù)器,也不再是一個簡單的反向代理了,。第二代的 openresty 致力于通過一系列 nginx 模塊,,把nginx擴(kuò)展為全功能的 web 應(yīng)用服務(wù)器。 ngx_openresty 是用戶驅(qū)動的項目,,后來也有不少國內(nèi)用戶的參與,,從 的點擊量分布上看,國內(nèi)和國外的點擊量基本持平,。 ngx_openresty 目前有兩大應(yīng)用目標(biāo):
KongKong基于OpenResty開發(fā),,也是流量層網(wǎng)關(guān), 是一個云原生,、快速,、可擴(kuò)展、分布式的Api 網(wǎng)關(guān),。繼承了OpenResty的高性能、易擴(kuò)展性等特點。Kong通過簡單的增加機(jī)器節(jié)點,,可以很容易的水平擴(kuò)展,。同時功能插件化,可通過插件來擴(kuò)展其能力。而且在任何基礎(chǔ)架構(gòu)上都可以運行。具有以下特性:
Kong解決了什么問題 當(dāng)我們決定對應(yīng)用進(jìn)行微服務(wù)改造時,應(yīng)用客戶端如何與微服務(wù)交互的問題也隨之而來,,畢竟服務(wù)數(shù)量的增加會直接導(dǎo)致部署授權(quán),、負(fù)載均衡,、通信管理、分析和改變的難度增加,。 面對以上問題,,API GATEWAY是一個不錯的解決方案,其所提供的訪問限制,、安全、流量控制,、分析監(jiān)控,、日志,、請求轉(zhuǎn)發(fā),、合成和協(xié)議轉(zhuǎn)換功能,可以解放開發(fā)者去把精力集中在具體邏輯的代碼,,而不是把時間花費在考慮如何解決應(yīng)用和其他微服務(wù)鏈接的問題上,。 圖片來自Kong官網(wǎng): 可以看到Kong解決的問題。專注于全局的Api管理策略,,全局流量監(jiān)控,、日志記錄、全局限流,、黑白名單控制,、接入請求到業(yè)務(wù)系統(tǒng)的負(fù)載均衡等。 Kong的優(yōu)點以及性能 在眾多 API GATEWAY 框架中,,Mashape 開源的高性能高可用API網(wǎng)關(guān)和API服務(wù)管理層——KONG(基于 NGINX+Lua)特點尤為突出,,它可以通過插件擴(kuò)展已有功能,,這些插件(使用 lua 編寫)在API請求響應(yīng)循環(huán)的生命周期中被執(zhí)行。于此同時,,KONG本身提供包括 HTTP 基本認(rèn)證,、密鑰認(rèn)證、CORS,、TCP,、UDP、文件日志,、API請求限流,、請求轉(zhuǎn)發(fā)及 NGINX 監(jiān)控等基本功能。目前,,Kong 在 Mashape 管理了超過 15,000 個 API,,為 200,000 開發(fā)者提供了每月數(shù)十億的請求支持。 Kong架構(gòu) Kong提供一些列的服務(wù),這就不得不談?wù)剝?nèi)部的架構(gòu): 首先最底層是基于Nginx, Nginx是高性能的基礎(chǔ)層, 一個良好的負(fù)載均衡,、反向代理器,然后在此基礎(chǔ)上增加Lua腳本庫,形成了OpenResty,攔截請求, 響應(yīng)生命周期,可以通過Lua編寫腳本,所以插件比較豐富,。 關(guān)于Kong的一些插件庫以及如何配置,可以參考簡書:開源API網(wǎng)關(guān)系統(tǒng)(Kong教程)入門到精通 Zuul1.0Zuul是所有從設(shè)備和web站點到Netflix流媒體應(yīng)用程序后端請求的前門。作為一個邊緣服務(wù)應(yīng)用程序,,Zuul被構(gòu)建來支持動態(tài)路由,、監(jiān)視、彈性和安全性,。它還可以根據(jù)需要將請求路由到多個Amazon自動伸縮組,。 Zuul使用了一系列不同類型的過濾器,使我們能夠快速靈活地將功能應(yīng)用到服務(wù)中,。 過濾器 過濾器是Zuul的核心功能,。它們負(fù)責(zé)應(yīng)用程序的業(yè)務(wù)邏輯,可以執(zhí)行各種任務(wù),。
Zuul提供了一個動態(tài)讀取、編譯和運行這些過濾器的框架,。過濾器之間不直接通信,,而是通過每個請求特有的RequestContext共享狀態(tài)。 下面是Zuul的一些過濾器: Incoming Incoming過濾器在請求被代理到Origin之前執(zhí)行,。這通常是執(zhí)行大部分業(yè)務(wù)邏輯的地方,。例如:認(rèn)證、動態(tài)路由,、速率限制,、DDoS保護(hù)、指標(biāo),。 Endpoint Endpoint過濾器負(fù)責(zé)基于incoming過濾器的執(zhí)行來處理請求,。Zuul有一個內(nèi)置的過濾器(ProxyEndpoint),,用于將請求代理到后端服務(wù)器,因此這些過濾器的典型用途是用于靜態(tài)端點,。例如:健康檢查響應(yīng),,靜態(tài)錯誤響應(yīng),404響應(yīng),。 Outgoing Outgoing過濾器在從后端接收到響應(yīng)以后執(zhí)行處理操作,。通常情況下,它們更多地用于形成響應(yīng)和添加指標(biāo),,而不是用于任何繁重的工作,。例如:存儲統(tǒng)計信息、添加/剝離標(biāo)準(zhǔn)標(biāo)題,、向?qū)崟r流發(fā)送事件,、gziping響應(yīng)。 過濾器類型 下面是與一個請求典型的生命周期對應(yīng)的標(biāo)準(zhǔn)的過濾器類型:
這些過濾器幫助我們執(zhí)行以下功能:
Zuul 1.0 請求生命周期 Netflix宣布了通用API網(wǎng)關(guān)Zuul的架構(gòu)轉(zhuǎn)型。Zuul原本采用同步阻塞架構(gòu),,轉(zhuǎn)型后叫作Zuul2,,采用異步非阻塞架構(gòu)。Zuul2和Zuul1在架構(gòu)方面的主要區(qū)別在于,,Zuul2運行在異步非阻塞的框架上,比如Netty,。Zuul1依賴多線程來支持吞吐量的增長,,而Zuul 2使用的Netty框架依賴事件循環(huán)和回調(diào)函數(shù)。 Zuul2.0Zuul 2.0 架構(gòu)圖 上圖是Zuul2的架構(gòu),,和Zuul1沒有本質(zhì)區(qū)別,,兩點變化:
Inbound Filters : 路由到 Origin 之前執(zhí)行,,可以用于身份驗證,、路由和裝飾請求 Endpoint Filters : 可用于返回靜態(tài)響應(yīng),否則內(nèi)置的ProxyEndpoint過濾器將請求路由到Origin Outbound Filters : 從Origin那里獲取響應(yīng)后執(zhí)行,,可以用于度量,、裝飾用戶的響應(yīng)或添加自定義header 有兩種類型的過濾器:sync 和 async。因為Zuul是運行在一個事件循環(huán)之上的,,因此從來不要在過濾中阻塞,。如果你非要阻塞,可以在一個異步過濾器中這樣做,,并且在一個單獨的線程池上運行,,否則可以使用同步過濾器。 上文提到過Zuul2開始采用了異步模型 優(yōu)勢是異步非阻塞模式啟動的線程很少,,基本上一個CPU core上只需啟一個事件環(huán)處理線程,,它使用的線程資源就很少,上下文切換(Context Switch)開銷也少,。非阻塞模式可以接受的連接數(shù)大大增加,,可以簡單理解為請求來了只需要進(jìn)隊列,這個隊列的容量可以設(shè)得很大,,只要不超時,,隊列中的請求都會被依次處理。 不足,異步模式讓編程模型變得復(fù)雜,。一方面Zuul2本身的代碼要比Zuul1復(fù)雜很多,,Zuul1的代碼比較容易看懂,Zuul2的代碼看起來就比較費勁,。另一方面異步模型沒有一個明確清晰的請求->處理->響應(yīng)執(zhí)行流程(call flow),,它的流程是通過事件觸發(fā)的,請求處理的流程隨時可能被切換斷開,,內(nèi)部實現(xiàn)要通過一些關(guān)聯(lián)id機(jī)制才能把整個執(zhí)行流再串聯(lián)起來,,這就給開發(fā)調(diào)試運維引入了很多復(fù)雜性,比如你在IDE里頭調(diào)試異步請求流就非常困難,。另外ThreadLocal機(jī)制在這種異步模式下就不能簡單工作,,因為只有一個事件環(huán)線程,不是每個請求一個線程,,也就沒有線程局部的概念,,所以對于CAT這種依賴于ThreadLocal才能工作的監(jiān)控工具,調(diào)用鏈埋點就不好搞(實際可以工作但需要進(jìn)行特殊處理),。 總體上,,異步非阻塞模式比較適用于IO密集型(IO bound)場景,這種場景下系統(tǒng)大部分時間在處理IO,CPU計算比較輕,,少量事件環(huán)線程就能處理,。 Zuul 2 與 Zuul 2 性能對比 圖片來源:Zuul's Journey to Non-Blocking Netflix給出了一個比較模糊的數(shù)據(jù),大致Zuul2的性能比Zuul1好20%左右,,這里的性能主要指每節(jié)點每秒處理的請求數(shù),。為什么說模糊呢?因為這個數(shù)據(jù)受實際測試環(huán)境,,流量場景模式等眾多因素影響,,你很難復(fù)現(xiàn)這個測試數(shù)據(jù)。即便這個20%的性能提升是確實的,,其實這個性能提升也并不大,,和異步引入的復(fù)雜性相比,,這20%的提升是否值得是個問題,。Netflix本身在其博文和ppt中也是有點含糊其詞,,甚至自身都有一些疑問的。 Spring Cloud GatewaySpringCloud Gateway 是 Spring Cloud 的一個全新項目,,該項目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術(shù)開發(fā)的網(wǎng)關(guān),,它旨在為微服務(wù)架構(gòu)提供一種簡單有效的統(tǒng)一的 API 路由管理方式,。 SpringCloud Gateway 作為 Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān),目標(biāo)是替代 Zuul,,在Spring Cloud 2.0以上版本中,,沒有對新版本的Zuul 2.0以上最新高性能版本進(jìn)行集成,仍然還是使用的Zuul 2.0之前的非Reactor模式的老版本,。而為了提升網(wǎng)關(guān)的性能,,SpringCloud Gateway是基于WebFlux框架實現(xiàn)的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty,。 Spring Cloud Gateway 的目標(biāo),,不僅提供統(tǒng)一的路由方式,并且基于 Filter 鏈的方式提供了網(wǎng)關(guān)基本的功能,,例如:安全,監(jiān)控/指標(biāo),,和限流,。 Spring Cloud Gateway 底層使用了高性能的通信框架Netty。 SpringCloud Gateway 特征 SpringCloud官方,,對SpringCloud Gateway 特征介紹如下: (1)基于 Spring Framework 5,,Project Reactor 和 Spring Boot 2.0 (2)集成 Hystrix 斷路器 (3)集成 Spring Cloud DiscoveryClient (4)Predicates 和 Filters 作用于特定路由,易于編寫的 Predicates 和 Filters (5)具備一些網(wǎng)關(guān)的高級功能:動態(tài)路由、限流,、路徑重寫 從以上的特征來說,,和Zuul的特征差別不大。SpringCloud Gateway和Zuul主要的區(qū)別,,還是在底層的通信框架上,。 簡單說明一下上文中的三個術(shù)語: Filter(過濾器) 和Zuul的過濾器在概念上類似,可以使用它攔截和修改請求,,并且對上游的響應(yīng),,進(jìn)行二次處理。過濾器為org.springframework.cloud.gateway.filter.GatewayFilter類的實例,。 Route(路由) 網(wǎng)關(guān)配置的基本組成模塊,,和Zuul的路由配置模塊類似。一個Route模塊由一個 ID,,一個目標(biāo) URI,,一組斷言和一組過濾器定義。如果斷言為真,,則路由匹配,,目標(biāo)URI會被訪問。 Predicate(斷言): 這是一個 Java 8 的 Predicate,,可以使用它來匹配來自 HTTP 請求的任何內(nèi)容,,例如 headers 或參數(shù)。斷言的輸入類型是一個 ServerWebExchange,。 幾種網(wǎng)關(guān)的對比
站在巨人的肩膀上1、Zuul's Journey to Non-Blocking 2,、Zuul 2 : The Netflix Journey to Asynchronous, Non-Blocking Systems __EOF__ 本文作者:等不到的口琴 本文鏈接:https://www.cnblogs.com/Courage129/p/14446586.html 關(guān)于博主:評論和私信會在第一時間回復(fù),。或者直接私信我,。 版權(quán)聲明:本博客所有文章除特別聲明外,,均采用 BY-NC-SA 許可協(xié)議。轉(zhuǎn)載請注明出處,! 聲援博主:如果您覺得文章對您有幫助,,可以點擊文章右下角【推薦】一下。您的鼓勵是博主的最大動力,! |
|