主頁 > 後端開發 > 公司新來一個同事,把網關系統設計的爐火純青!(萬能通用,穩的一批。。)

公司新來一個同事,把網關系統設計的爐火純青!(萬能通用,穩的一批。。)

2022-12-16 06:51:42 後端開發

來源:developer.aliyun.com/article/889271

本文準備圍繞七個點來講網關,分別是網關的基本概念、網關設計思路、網關設計重點、流量網關、業務網關、常見網關對比,對基礎概念熟悉的朋友可以根據目錄查看自己感興趣的部分,

什么是網關

網關,很多地方將網關比如成門, 沒什么問題, 但是需要區分網關與網橋的區別,

網橋 作業在資料鏈路層,在不同或相同型別的LAN之間存盤并轉發資料幀,必要時進行鏈路層上的協議轉換,可連接兩個或多個網路,在其中傳送資訊包,

網關 是一個大概念,不具體特指一類產品,只要連接兩個不同的網路都可以叫網關,網橋一般只轉發資訊,而網關可能進行包裝,

網關通俗理解

根據網關的特性,舉個例子:

假如你要去找集團老板(這兒只是舉個例子), 大家都知道老板肯定不是誰想見就能見的, 也怕壞人嘛, 那么你去老板所在的辦公樓,假如是集團總部, 大樓這個門就充當了網關的角色, 大門一般都有看門員 ,看門員會做哪些事情呢?

首先所有想見老板的人肯定都得從這個門進(統一入口 ), 這個門相當于將辦公室和外界隔離了,主要為了保護里面的安全以及正常作業, 來到這個門之后, 門衛肯定會讓你出示相關證件(鑒權檢驗 ), 意思就是判斷你要見老板這個請求是否合理, 如果不合理直接就拒絕了, 讓你回家等訊息 , 如果鑒權之后, 發現你找老板其實只是為了和他談談兩元店的生意, 門衛會跟你說這個用不著找老板, 你去集團投資部就行了(動態路由 , 將請求路由到不同的后端集群中), 此時會對你進行一些包裝 ,例如給你出具一個訪問證類似的,然后告訴你路該怎么走,等等,

你看看,網關的作用是不是就是這三個, 最終目的就是減少你與集團的耦合,具體到計算機上就是減少客戶端與服務端的耦合,如果沒有網關意味著所有請求都會直接呼叫服務器上的資源,這樣耦合太強了,服務器出了問題,客戶端會直接報錯, 例如老板換作業的地方了,如果沒有網關你直接去原來的地方找, 肯定會被告知老板不在這兒,

為什么需要網關

當使用單體應用程式架構時,客戶端(Web 或移動端)通過向后端應用程式發起一次 REST 呼叫來獲取資料,負載均衡器將請求路由給 N 個相同的應用程式實體中的一個,然后應用程式會查詢各種資料庫表,并將回應回傳給客戶端,微服務架構下,單體應用被切割成多個微服務,如果將所有的微服務直接對外暴露,勢必會出現安全方面的各種問題,另外內外耦合嚴重,

客戶端可以直接向每個微服務發送請求,其問題主要如下:

  • 客戶端需求和每個微服務暴露的細粒度 API 不匹配,
  • 部分服務使用的協議不是Web友好協議,可能使用 Thrift 二進制 RPC,也可能使用 AMQP 訊息傳遞協議,
  • 微服務難以重構,如果合并兩個服務,或者將一個服務拆分成兩個或更多服務,這類重構就非常困難了,

服務端的各個服務直接暴露給客戶端呼叫勢必會引起各種問題,同時,服務端的各個服務可擴展和伸縮性很差,API 網關是微服務架構中的基礎組件,位于接入層之下和業務服務層之上,如前所述的這些功能適合在 API 網關實作,

網關與服務器集群

回到我們服務器上,下面圖介紹了網關(Gateway)作用,可知 Gateway 方式下的架構,可以細到為每一個服務的實體配置一個自己的 Gateway,也可以粗到為一組服務配置一個,甚至可以粗到為整個架構配置一個接入的 Gateway,于是,整個系統架構的復雜度就會變得簡單可控起來,

這張圖展示了一個多層 Gateway 架構,其中有一個總的 Gateway 接入所有的流量(流量網關 ),并分發給不同的子系統,還有第二級 Gateway 用于做各個子系統的接入 Gateway(業務網關 ),可以看到,網關所管理的服務粒度可粗可細,通過網關,我們可以把分布式架構組織成一個星型架構,由網路對服務的請求進行路由和分發,下面來聊聊好的網關應該具備哪些功能,也就是網關設計模式,

網關設計思路

如果你想系統學習最新的基于 Spring Cloud Gateway 的微服務,建議你報名堆疊長的《Spring Cloud 微服務課程》,一次訂閱,永久免費提供更新,

一個網關需要有以下的功能:

1. 請求路由

網關一定要有請求路由的功能,這樣一來,對于呼叫端來說,也是一件非常方便的事情,因為呼叫端不需要知道自己需要用到的其它服務的地址,全部統一地交給 Gateway 來處理,

2. 服務注冊

為了能夠代理后面的服務,并把請求路由到正確的位置上,網關應該有服務注冊功能,也就是后端的服務實體可以把其提供服務的地址注冊、取消注冊,一般來說,注冊也就是注冊一些 API 介面,比如,HTTP 的 Restful 請求,可以注冊相應 API 的 URI、方法、HTTP 頭,這樣,Gateway 就可以根據接收到的請求中的資訊來決定路由到哪一個后端的服務上,

3. 負載均衡

因為一個網關可以接收多個服務實體,所以網關還需要在各個對等的服務實體上做負載均衡策略,簡單點就是直接 Round-Robin 輪詢,復雜點的可以設定上權重進行分發,再復雜一點還可以做到 session 粘連,

4. 彈力設計

網關還可以把彈力設計中的那些異步、重試、冪等、流控、熔斷、監視等都可以實作進去,這樣,同樣可以像 Service Mesh 那樣,讓應用服務只關心自己的業務邏輯(或是說資料面上的事)而不是控制邏輯(控制面),

5. 安全方面

SSL 加密及證書管理、Session 驗證、授權、資料校驗,以及對請求源進行惡意攻擊的防范,錯誤處理越靠前的位置就是越好,所以,網關可以做到一個全站的接入組件來對后端的服務進行保護,當然,網關還可以做更多更有趣的事情,比如:灰度發布、API聚合、API編排,

灰度發布

網關完全可以做到對相同服務不同版本的實體進行導流,還可以收集相關的資料,這樣對于軟體質量的提升,甚至產品試錯都有非常積極的意義,

API 聚合

使用網關可以將多個單獨請求聚合成一個請求,在微服務體系的架構中,因為服務變小了,所以一個明顯的問題是,客戶端可能需要多次請求才能得到所有的資料,這樣一來,客戶端與后端之間的頻繁通信會對應用程式的性能和規模產生非常不利的影響,于是,我們可以讓網關來幫客戶端請求多個后端的服務(有些場景下完全可以并發請求),然后把后端服務的回應結果拼裝起來,回傳給客戶端(當然,這個程序也可以做成異步的,但這需要客戶端的配合),

API 編排

同樣在微服務的架構下,要走完一個完整的業務流程,我們需要呼叫一系列 API,就像一種作業流一樣,這個事完全可以通過網頁來編排這個業務流程,我們可能通過一個 DSL 來定義和編排不同的 API,也可以通過像 AWS Lambda 服務那樣的方式來串聯不同的 API,

網關設計重點

網關設計重點主要是三個, 高性能、高可用、高擴展:

1. 高性能

在技術設計上,網關不應該也不能成為性能的瓶頸,對于高性能,最好使用高性能的編程語言來實作,如 C、C++、Go 和 Java,網關對后端的請求,以及對前端的請求的服務一定要使用異步非阻塞的 I/O 來確保后端延遲不會導致應用程式中出現性能問題,C 和 C++ 可以參看 Linux 下的 epoll 和 Windows 的 I/O Completion Port 的異步 IO 模型,Java 下如 Netty、Spring Reactor 的 NIO 框架,

2. 高可用

因為所有的流量或呼叫經過網關,所以網關必須成為一個高可用的技術組件,它的穩定直接關系到了所有服務的穩定,網關如果沒有設計,就會成變一個單點故障,因此,一個好的網關至少要做到以下幾點,

  • 集群化 ,網關要成為一個集群,其最好可以自己組成一個集群,并可以自己同步集群資料,而不需要依賴于一個第三方系統來同步資料,
  • 服務化 ,網關還需要做到在不間斷的情況下修改配置,一種是像 Nginx reload 配置那樣,可以做到不停服務,另一種是最好做到服務化,也就是說,得要有自己的 Admin API 來在運行時修改自己的配置,
  • 持續化 ,比如重啟,就是像 Nginx 那樣優雅地重啟,有一個主管請求分發的主行程,當我們需要重啟時,新的請求被分配到新的行程中,而老的行程處理完正在處理的請求后就退出,

3. 高擴展

因為網關需要承接所有的業務流量和請求,所以一定會有或多或少的業務邏輯,而我們都知道,業務邏輯是多變和不確定的,比如,需要在網關上加入一些和業務相關的東西,因此,一個好的 Gateway 還需要是可以擴展的,并能進行二次開發的,當然,像 Nginx 那樣通過 Module 進行二次開發的固然可以,

另外,在運維方面 ,網關應該有以下幾個設計原則,

  • 業務松耦合,協議緊耦合 ,在業務設計上,網關不應與后面的服務之間形成服務耦合,也不應該有業務邏輯,網關應該是在網路應用層上的組件,不應該處理通訊協議體,只應該決議和處理通訊協議頭,另外,除了服務發現外,網關不應該有第三方服務的依賴,
  • 應用監視,提供分析資料 ,網關上需要考慮應用性能的監控,除了有相應后端服務的高可用的統計之外,還需要使用 Tracing ID 實施分布式鏈路跟蹤,并統計好一定時間內每個 API 的吞吐量、回應時間和回傳碼,以便啟動彈力設計中的相應策略,
  • 用彈力設計保護后端服務 ,網關上一定要實作熔斷、限流、重試和超時等彈力設計,如果一個或多個服務呼叫花費的時間過長,那么可接受超時并回傳一部分資料,或是回傳一個網關里的快取的上一次成功請求的資料,你可以考慮一下這樣的設計,
  • DevOps ,因為網關這個組件太關鍵了,所以需要 DevOps 這樣的東西,將其發生故障的概率降到最低,這個軟體需要經過精良的測驗,包括功能和性能的測驗,還有浸泡測驗,還需要有一系列自動化運維的管控工具,

網關設計注意事項

  1. 不要在網關中的代碼里內置聚合后端服務的功能,而應考慮將聚合服務放在網關核心代碼之外,可以使用 Plugin 的方式,也可以放在網關后面形成一個 Serverless 服務,
  2. 網關應該靠近后端服務,并和后端服務使用同一個內網,這樣可以保證網關和后端服務呼叫的低延遲,并可以減少很多網路上的問題,這里多說一句,網關處理的靜態內容應該靠近用戶(應該放到 CDN 上),而網關和此時的動態服務應該靠近后端服務,
  3. 網關也需要做容量擴展,所以需要成為一個集群來分擔前端帶來的流量,這一點,要么通過 DNS 輪詢的方式實作,要么通過 CDN 來做流量調度,或者通過更為底層的性能更高的負載均衡設備,
  4. 對于服務發現,可以做一個時間不長的快取,這樣不需要每次請求都去查一下相關的服務所在的地方,當然,如果你的系統不復雜,可以考慮把服務發現的功能直接集成進網關中,
  5. 為網關考慮 bulkhead 設計方式,用不同的網關服務不同的后端服務,或是用不同的網關服務前端不同的客戶,

另外,因為網關是為用戶請求和后端服務的橋接裝置,所以需要考慮一些安全方面的事宜,具體如下:

  1. 加密資料 ,可以把 SSL 相關的證書放到網關上,由網關做統一的 SSL 傳輸管理,
  2. 校驗用戶的請求 ,一些基本的用戶驗證可以放在網關上來做,比如用戶是否已登錄,用戶請求中的 token 是否合法等,但是,我們需要權衡一下,網關是否需要校驗用戶的輸入,因為這樣一來,網關就需要從只關心協議頭,到需要關心協議體,而協議體中的東西一方面不像協議頭是標準的,另一方面決議協議體還要耗費大量的運行時間,從而降低網關的性能,對此,我想說的是,看具體需求,一方面如果協議體是標準的,那么可以干;另一方面,對于決議協議所帶來的性能問題,需要做相應的隔離,
  3. 檢測例外訪問 ,網關需要檢測一些例外訪問,比如,在一段比較短的時間內請求次數超過一定數值;還比如,同一客戶端的 4xx 請求出錯率太高……對于這樣的一些請求訪問,網關一方面要把這樣的請求屏蔽掉,另一方面需要發出警告,有可能會是一些比較重大的安全問題,如被黑客攻擊,

流量網關

流量網關,顧名思義就是控制流量進入集群的網關,有很多作業需要在這一步做,對于一個服務集群,勢必有很多非法的請求或者無效的請求,這時候要將請求拒之門外,降低集群的流量壓力,

定義全域性的、跟具體的后端業務應用和服務完全無關的策略網關就是上圖所示的架構模型——流量網關,流量網關通常只專注于全域的Api管理策略,比如全域流量監控、日志記錄、全域限流、黑白名單控制、接入請求到業務系統的負載均衡等,有點類似防火墻,Kong 就是典型的流量網關,

下面是kong的架構圖,來自官網:https://konghq.com

這里需要補充一點的是,業務網關一般部署在流量網關之后、業務系統之前,比流量網關更靠近業務系統,通常API網指的是業務網關,有時候我們也會模糊流量網關和業務網關,讓一個網關承擔所有的作業,所以這兩者之間并沒有嚴格的界線,

推薦一個開源免費的 Spring Boot 最全教程:

https://github.com/javastacks/spring-boot-best-practice

業務網關

當一個單體應用被拆分成許許多多的微服務應用后,也帶來了一些問題,一些與業務非強相關的功能,比如權限控制、日志輸出、資料加密、熔斷限流等,每個微服務應用都需要,因此存在著大量重復的代碼實作,而且由于系統的迭代、人員的更替,各個微服務中這些功能的實作細節出現了較大的差異,導致維護成本變高,另一方面,原先單體應用下非常容易做的介面管理,在服務拆分后沒有了一個集中管理的地方,無法統計已存在哪些介面、介面定義是什么、運行狀態如何,

網關就是為了解決上述問題,作為微服務體系中的核心基礎設施,一般需要具備介面管理、協議適配、熔斷限流、安全防護等功能,各種開源的網關產品(比如 zuul)都提供了優秀高可擴展性的架構、可以很方便的實作我們需要的一些功能、比如鑒權、日志監控、熔斷限流等,

與流量網關相對應的就是業務網關,業務網關更靠近我們的業務,也就是與服務器應用層打交道,那么有很多應用層需要考慮的事情就可以依托業務網關,例如在執行緒模型、協議適配、熔斷限流,服務編排等,下面看看業務網關體系結構:

從這個途中可以看出業務網關主要職責以及所做的事情, 目前業務網關比較成熟的 API 網關框架產品有三個 分別是:Zuul1、Zuul2 和 SpringCloud Gateway, 后面再進行對比,

常見網關對比

既然對比,就先宏觀上對各種網關有一個了解,后面再挑一些常用的或者說應用廣泛的詳細了解,

目前常見的開源網關大致上按照語言分類有如下幾類:

  • Nginx+lua :OpenResty、Kong、Orange、Abtesting gateway 等
  • Java :Zuul/Zuul2、Spring Cloud Gateway、Kaazing KWG、gravitee、Dromara soul 等
  • Go :Janus、fagongzi、Grpc-gateway
  • Dotnet :Ocelot
  • NodeJS :Express Gateway、Micro Gateway

按照使用數量、成熟度等來劃分,主流的有 5個:

  • OpenResty
  • Kong
  • Zuul、Zuul2
  • Spring Cloud Gateway

1. OpenResty

OpenResty是一個流量網關,根據前面對流量網關的介紹就可以知道流量網關的指責,

OpenResty基于 Nginx與 Lua 的高性能 Web 平臺,其內部集成了大量精良的 Lua 庫、第三方模塊以及大多數的依賴項,用于方便地搭建能夠處理超高并發、擴展性極高的動態 Web 應用、Web 服務和動態網關,

通過揉和眾多設計良好的 Nginx 模塊,OpenResty 有效地把 Nginx 服務器轉變為一個強大的 Web 應用服務器,基于它開發人員可以使用 Lua 編程語言對 Nginx 核心以及現有的各種 Nginx C 模塊進行腳本編程,構建出可以處理一萬以上并發請求的極端高性能的 Web 應用

OpenResty 最早是順應 OpenAPI 的潮流做的,所以 Open 取自“開放”之意,而Resty便是 REST 風格的意思,雖然后來也可以基于 ngx_openresty 實作任何形式的 web service 或者傳統的 web 應用,

也就是說 Nginx 不再是一個簡單的靜態網頁服務器,也不再是一個簡單的反向代理了,第二代的 openresty 致力于通過一系列 nginx 模塊,把nginx擴展為全功能的 web 應用服務器,

ngx_openresty 是用戶驅動的專案,后來也有不少國內用戶的參與,從 openresty.org 的點擊量分布上看,國內和國外的點擊量基本持平,

ngx_openresty 目前有兩大應用目標:

  1. 通用目的的 web 應用服務器,在這個目標下,現有的 web 應用技術都可以算是和 OpenResty 或多或少有些類似,比如 Nodejs, PHP 等等,ngx_openresty 的性能(包括記憶體使用和 CPU 效率)算是最大的賣點之一,
  2. Nginx 的腳本擴展編程,用于構建靈活的 Web 應用網關和 Web 應用防火墻,有些類似的是 NetScaler,其優勢在于 Lua 編程帶來的巨大靈活性,

2. Kong

Kong基于OpenResty開發,也是流量層網關, 是一個云原生、快速、可擴展、分布式的Api 網關,繼承了OpenResty的高性能、易擴展性等特點,Kong通過簡單的增加機器節點,可以很容易的水平擴展,同時功能插件化,可通過插件來擴展其能力,而且在任何基礎架構上都可以運行,具有以下特性:

  • 提供了多樣化的認證層來保護Api,
  • 可對出入流量進行管制,
  • 提供了可視化的流量檢查、監視分析Api,
  • 能夠及時的轉換請求和相應,
  • 提供log解決方案
  • 可通過api呼叫Serverless 函式,

Kong解決了什么問題

當我們決定對應用進行微服務改造時,應用客戶端如何與微服務互動的問題也隨之而來,畢竟服務數量的增加會直接導致部署授權、負載均衡、通信管理、分析和改變的難度增加,

面對以上問題,API GATEWAY是一個不錯的解決方案,其所提供的訪問限制、安全、流量控制、分析監控、日志、請求轉發、合成和協議轉換功能,可以解放開發者去把精力集中在具體邏輯的代碼,而不是把時間花費在考慮如何解決應用和其他微服務鏈接的問題上,

圖片來自Kong官網:

可以看到Kong解決的問題,專注于全域的Api管理策略,全域流量監控、日志記錄、全域限流、黑白名單控制、接入請求到業務系統的負載均衡等,

Kong的優點以及性能

在眾多 API GATEWAY 框架中,Mashape 開源的高性能高可用API網關和API服務管理層——KONG(基于 NGINX+Lua)特點尤為突出,它可以通過插件擴展已有功能,這些插件(使用 lua 撰寫)在API請求回應回圈的生命周期中被執行,于此同時,KONG本身提供包括 HTTP 基本認證、密鑰認證、CORS、TCP、UDP、檔案日志、API請求限流、請求轉發及 NGINX 監控等基本功能,目前,Kong 在 Mashape 管理了超過 15,000 個 API,為 200,000 開發者提供了每月數十億的請求支持,

Kong架構

Kong提供一些列的服務,這就不得不談談內部的架構:

首先最底層是基于Nginx, Nginx是高性能的基礎層, 一個良好的負載均衡、反向代理器,然后在此基礎上增加Lua腳本庫,形成了OpenResty,攔截請求, 回應生命周期,可以通過Lua撰寫腳本,所以插件比較豐富,

3. Zuul1.0

Zuul是所有從設備和web站點到Netflix流媒體應用程式后端請求的前門,作為一個邊緣服務應用程式,Zuul被構建來支持動態路由、監視、彈性和安全性,它還可以根據需要將請求路由到多個Amazon自動伸縮組,

Zuul使用了一系列不同型別的過濾器,使我們能夠快速靈活地將功能應用到服務中,

過濾器

過濾器是Zuul的核心功能,它們負責應用程式的業務邏輯,可以執行各種任務,

  • Type :通常定義過濾器應用在哪個階段
  • Async :定義過濾器是同步還是異步
  • Execution Order :執行順序
  • Criteria :過濾器執行的條件
  • Action :如果條件滿足,過濾器執行的動作

Zuul提供了一個動態讀取、編譯和運行這些過濾器的框架,過濾器之間不直接通信,而是通過每個請求特有的RequestContext共享狀態,

下面是Zuul的一些過濾器:

Incoming

Incoming過濾器在請求被代理到Origin之前執行,這通常是執行大部分業務邏輯的地方,例如:認證、動態路由、速率限制、DDoS保護、指標,

Endpoint

Endpoint過濾器負責基于incoming過濾器的執行來處理請求,Zuul有一個內置的過濾器(ProxyEndpoint),用于將請求代理到后端服務器,因此這些過濾器的典型用途是用于靜態端點,例如:健康檢查回應,靜態錯誤回應,404回應,

Outgoing

Outgoing過濾器在從后端接收到回應以后執行處理操作,通常情況下,它們更多地用于形成回應和添加指標,而不是用于任何繁重的作業,例如:存盤統計資訊、添加/剝離標準標題、向實時流發送事件、gziping回應,

過濾器型別

下面是與一個請求典型的生命周期對應的標準的過濾器型別:

  • PRE :路由到Origin之前執行
  • ROUTING :路由到Origin期間執行
  • POST :請求被路由到Origin之后執行
  • ERROR :發生錯誤的時候執行

這些過濾器幫助我們執行以下功能:

  • 身份驗證和安全性 :識別每個資源的身份驗證需求,并拒絕不滿足它們的請求
  • 監控 :在邊緣跟蹤有意義的資料和統計資料,以便給我們一個準確的生產視圖
  • 動態路由 :動態路由請求到不同的后端集群
  • 壓力測驗 :逐漸增加集群的流量,以評估性能
  • 限流 :為每種請求型別分配容量,并丟棄超過限制的請求
  • 靜態回應處理 :直接在邊緣構建一些回應,而不是將它們轉發到內部集群

Zuul 1.0 請求生命周期

Netflix宣布了通用API網關Zuul的架構轉型,Zuul原本采用同步阻塞架構,轉型后叫作Zuul2,采用異步非阻塞架構,Zuul2和Zuul1在架構方面的主要區別在于,Zuul2運行在異步非阻塞的框架上,比如Netty,Zuul1依賴多執行緒來支持吞吐量的增長,而Zuul 2使用的Netty框架依賴事件回圈和回呼函式,

4. Zuul2.0

Zuul 2.0 架構圖

上圖是Zuul2的架構,和Zuul1沒有本質區別,兩點變化:

  1. 前端用Netty Server代替Servlet,目的是支持前端異步,后端用Netty Client代替Http Client,目的是支持后端異步,
  2. 過濾器換了一下名字,用Inbound Filters代替Pre-routing Filters,用Endpoint Filter代替Routing Filter,用Outbound Filters代替Post-routing Filters,

Inbound Filters :路由到 Origin 之前執行,可以用于身份驗證、路由和裝飾請求

Endpoint Filters :可用于回傳靜態回應,否則內置的ProxyEndpoint過濾器將請求路由到Origin

Outbound Filters :從Origin那里獲取回應后執行,可以用于度量、裝飾用戶的回應或添加自定義header

有兩種型別的過濾器:sync 和 async,因為Zuul是運行在一個事件回圈之上的,因此從來不要在過濾中阻塞,如果你非要阻塞,可以在一個異步過濾器中這樣做,并且在一個單獨的執行緒池上運行,否則可以使用同步過濾器,

上文提到過Zuul2開始采用了異步模型

優勢 是異步非阻塞模式啟動的執行緒很少,基本上一個CPU core上只需啟一個事件環處理執行緒,它使用的執行緒資源就很少,背景關系切換(Context Switch)開銷也少,非阻塞模式可以接受的連接數大大增加,可以簡單理解為請求來了只需要進佇列,這個佇列的容量可以設得很大,只要不超時,佇列中的請求都會被依次處理,

不足 ,異步模式讓編程模型變得復雜,一方面Zuul2本身的代碼要比Zuul1復雜很多,Zuul1的代碼比較容易看懂,Zuul2的代碼看起來就比較費勁,另一方面異步模型沒有一個明確清晰的請求->處理->回應執行流程(call flow),它的流程是通過事件觸發的,請求處理的流程隨時可能被切換斷開,內部實作要通過一些關聯id機制才能把整個執行流再串聯起來,這就給開發除錯運維引入了很多復雜性,比如你在IDE里頭除錯異步請求流就非常困難,另外ThreadLocal機制在這種異步模式下就不能簡單作業,因為只有一個事件環執行緒,不是每個請求一個執行緒,也就沒有執行緒區域的概念,所以對于CAT這種依賴于ThreadLocal才能作業的監控工具,呼叫鏈埋點就不好搞(實際可以作業但需要進行特殊處理),

總體上,異步非阻塞模式比較適用于IO密集型(IO bound)場景,這種場景下系統大部分時間在處理IO,CPU計算比較輕,少量事件環執行緒就能處理,

Zuul 與 Zuul 2 性能對比

Netflix給出了一個比較模糊的資料,大致Zuul2的性能比Zuul1好20%左右 ,這里的性能主要指每節點每秒處理的請求數,為什么說模糊呢?因為這個資料受實際測驗環境,流量場景模式等眾多因素影響,你很難復現這個測驗資料,即便這個20%的性能提升是確實的,其實這個性能提升也并不大,和異步引入的復雜性相比,這20%的提升是否值得是個問題,Netflix本身在其博文22和ppt11中也是有點含糊其詞,甚至自身都有一些疑問的,

5. Spring Cloud Gateway

SpringCloud Gateway 是 Spring Cloud 的一個全新專案,該專案是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技術開發的網關,它旨在為微服務架構提供一種簡單有效的統一的 API 路由管理方式,

SpringCloud Gateway 作為 Spring Cloud 生態系統中的網關,目標是替代 Zuul,在Spring Cloud 2.0以上版本中,沒有對新版本的Zuul 2.0以上最新高性能版本進行集成,仍然還是使用的Zuul 2.0之前的非Reactor模式的老版本,而為了提升網關的性能,SpringCloud Gateway是基于WebFlux框架實作的,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty,

Spring Cloud Gateway 的目標,不僅提供統一的路由方式,并且基于 Filter 鏈的方式提供了網關基本的功能,例如:安全,監控/指標,和限流,

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)具備一些網關的高級功能:動態路由、限流、路徑重寫

從以上的特征來說,和Zuul的特征差別不大,SpringCloud Gateway和Zuul主要的區別,還是在底層的通信框架上,

簡單說明一下上文中的三個術語:

Filter (過濾器)

和Zuul的過濾器在概念上類似,可以使用它攔截和修改請求,并且對上游的回應,進行二次處理,過濾器為org.springframework.cloud.gateway.filter.GatewayFilter類的實體,

Route (路由)

網關配置的基本組成模塊,和Zuul的路由配置模塊類似,一個Route模塊 由一個 ID,一個目標 URI,一組斷言和一組過濾器定義,如果斷言為真,則路由匹配,目標URI會被訪問,

Predicate (斷言):

這是一個 Java 8 的 Predicate,可以使用它來匹配來自 HTTP 請求的任何內容,例如 headers 或引數,斷言的 輸入型別是一個 ServerWebExchange,

幾種網關的對比

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了,,,

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發布,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/539999.html

標籤:其他

上一篇:Shell 標準輸入和輸出

下一篇:java+Selenium(一)八種元素獲取方式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more