閘道器技術解析
本文目錄:
閘道器的基本概念
閘道器設計思路
閘道器設計重點
閘道器設計注意事項
流量閘道器
業務閘道器
常見閘道器對比
什麼是閘道器
閘道器,很多地方將閘道器比如成門, 沒什麼問題, 但是需要區分閘道器與網橋的區別,
網橋 工作在資料鏈路層,在不同或相同型別的LAN之間儲存並轉發資料幀,必要時進行鏈路層上的協議轉換。可連線兩個或多個網路,在其中傳送資訊包。
閘道器 是一個大概念,不具體特指一類產品,只要連線兩個不同的網路都可以叫閘道器,網橋一般只轉發信息,而閘道器可能進行包裝。
閘道器通俗理解
根據閘道器的特性,舉個例子:
假如你要去找集團老闆(這兒只是舉個例子), 大家都知道老闆肯定不是誰想見就能見的, 也怕壞人嘛, 那麼你去老闆所在的辦公樓,假如是集團總部, 大樓這個門就充當了閘道器的角色, 大門一般都有看門員 ,看門員會做哪些事情呢?
首先所有想見老闆的人肯定都得從這個門進(統一入口 ), 這個門相當於將辦公室和外界隔離了,主要為了保護裡面的安全以及正常工作, 來到這個門之後, 門衛肯定會讓你出示相關證件(鑑權檢驗 ), 意思就是判斷你要見老闆這個請求是否合理, 如果不合理直接就拒絕了, 讓你回家等訊息 , 如果鑑權之後, 發現你找老闆其實只是為了和他談談兩元店的生意, 門衛會跟你說這個用不著找老闆, 你去集團投資部就行了(動態路由 , 將請求路由到不同的後端叢集中), 此時會對你進行一些包裝 ,例如給你出具一個訪問證類似的,然後告訴你路該怎麼走,等等。
你看看,閘道器的作用是不是就是這三個, 最終目的就是減少你與集團的耦合,具體到計算機上就是減少客戶端與服務端的耦合,如果沒有閘道器意味著所有請求都會直接呼叫伺服器上的資源,這樣耦合太強了,伺服器出了問題,客戶端會直接報錯, 例如老闆換工作的地方了,如果沒有閘道器你直接去原來的地方找, 肯定會被告知老闆不在這兒。
為什麼需要閘道器
當使用單體應用程式架構時,客戶端(Web 或移動端)通過向後端應用程式發起一次 REST 呼叫來獲取資料。負載均衡器將請求路由給 N 個相同的應用程式例項中的一個。然後應用程式會查詢各種資料庫表,並將響應返回給客戶端。微服務架構下,單體應用被切割成多個微服務,如果將所有的微服務直接對外暴露,勢必會出現安全方面的各種問題,另外內外耦合嚴重。
客戶端可以直接向每個微服務傳送請求,其問題主要如下:
- 客戶端需求和每個微服務暴露的細粒度 API 不匹配。
- 部分服務使用的協議不是Web友好協議。可能使用 Thrift 二進位制 RPC,也可能使用 AMQP 訊息傳遞協議。
- 微服務難以重構。如果合併兩個服務,或者將一個服務拆分成兩個或更多服務,這類重構就非常困難了。
服務端的各個服務直接暴露給客戶端呼叫勢必會引起各種問題。同時,服務端的各個服務可擴充套件和伸縮性很差。API 閘道器是微服務架構中的基礎元件,位於接入層之下和業務服務層之上,如前所述的這些功能適合在 API 閘道器實現。
閘道器與伺服器叢集
回到我們伺服器上,下面圖介紹了閘道器(Gateway)作用,可知 Gateway 方式下的架構,可以細到為每一個服務的例項配置一個自己的 Gateway,也可以粗到為一組服務配置一個,甚至可以粗到為整個架構配置一個接入的 Gateway。於是,整個系統架構的複雜度就會變得簡單可控起來。
這張圖展示了一個多層 Gateway 架構,其中有一個總的 Gateway 接入所有的流量(流量閘道器 ),並分發給不同的子系統,還有第二級 Gateway 用於做各個子系統的接入 Gateway(業務閘道器 )。可以看到,閘道器所管理的服務粒度可粗可細。通過閘道器,我們可以把分散式架構組織成一個星型架構,由網路對服務的請求進行路由和分發。下面來聊聊好的閘道器應該具備哪些功能,也就是閘道器設計模式。
閘道器設計思路
一個閘道器需要有以下的功能:
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 這樣的東西,將其發生故障的概率降到最低。這個軟體需要經過精良的測試,包括功能和效能的測試,還有浸泡測試。還需要有一系列自動化運維的管控工具。
閘道器設計注意事項
- 不要在閘道器中的程式碼裡內建聚合後端服務的功能,而應考慮將聚合服務放在閘道器核心程式碼之外。可以使用 Plugin 的方式,也可以放在閘道器後面形成一個 Serverless 服務。
- 閘道器應該靠近後端服務,並和後端服務使用同一個內網,這樣可以保證閘道器和後端服務呼叫的低延遲,並可以減少很多網路上的問題。這裡多說一句,閘道器處理的靜態內容應該靠近使用者(應該放到 CDN 上),而閘道器和此時的動態服務應該靠近後端服務。
- 閘道器也需要做容量擴充套件,所以需要成為一個叢集來分擔前端帶來的流量。這一點,要麼通過 DNS 輪詢的方式實現,要麼通過 CDN 來做流量排程,或者通過更為底層的效能更高的負載均衡裝置。
- 對於服務發現,可以做一個時間不長的快取,這樣不需要每次請求都去查一下相關的服務所在的地方。當然,如果你的系統不復雜,可以考慮把服務發現的功能直接整合進閘道器中。
- 為閘道器考慮 bulkhead 設計方式。用不同的閘道器服務不同的後端服務,或是用不同的閘道器服務前端不同的客戶。
另外,因為閘道器是為使用者請求和後端服務的橋接裝置,所以需要考慮一些安全方面的事宜。具體如下:
- 加密資料 。可以把 SSL 相關的證書放到閘道器上,由閘道器做統一的 SSL 傳輸管理。
- 校驗使用者的請求 。一些基本的使用者驗證可以放在閘道器上來做,比如使用者是否已登入,使用者請求中的 token 是否合法等。但是,我們需要權衡一下,閘道器是否需要校驗使用者的輸入。因為這樣一來,閘道器就需要從只關心協議頭,到需要關心協議體。而協議體中的東西一方面不像協議頭是標準的,另一方面解析協議體還要耗費大量的執行時間,從而降低閘道器的效能。對此,我想說的是,看具體需求,一方面如果協議體是標準的,那麼可以幹;另一方面,對於解析協議所帶來的效能問題,需要做相應的隔離。
- 檢測異常訪問 。閘道器需要檢測一些異常訪問,比如,在一段比較短的時間內請求次數超過一定數值;還比如,同一客戶端的 4xx 請求出錯率太高……對於這樣的一些請求訪問,閘道器一方面要把這樣的請求遮蔽掉,另一方面需要發出警告,有可能會是一些比較重大的安全問題,如被黑客攻擊。
流量閘道器
流量閘道器,顧名思義就是控制流量進入叢集的閘道器,有很多工作需要在這一步做,對於一個服務叢集,勢必有很多非法的請求或者無效的請求,這時候要將請求拒之門外,降低叢集的流量壓力。
定義全域性性的、跟具體的後端業務應用和服務完全無關的策略閘道器就是上圖所示的架構模型——流量閘道器。流量閘道器通常只專注於全域性的Api管理策略,比如全域性流量監控、日誌記錄、全侷限流、黑白名單控制、接入請求到業務系統的負載均衡等,有點類似防火牆。Kong 就是典型的流量閘道器。
下面是kong的架構圖,來自官網:https://konghq.com
這裡需要補充一點的是,業務閘道器一般部署在流量閘道器之後、業務系統之前,比流量閘道器更靠近業務系統。通常API網指的是業務閘道器。有時候我們也會模糊流量閘道器和業務閘道器,讓一個閘道器承擔所有的工作,所以這兩者之間並沒有嚴格的界線。
業務閘道器
當一個單體應用被拆分成許許多多的微服務應用後,也帶來了一些問題。一些與業務非強相關的功能,比如許可權控制、日誌輸出、資料加密、熔斷限流等,每個微服務應用都需要,因此存在著大量重複的程式碼實現。而且由於系統的迭代、人員的更替,各個微服務中這些功能的實現細節出現了較大的差異,導致維護成本變高。另一方面,原先單體應用下非常容易做的介面管理,在服務拆分後沒有了一個集中管理的地方,無法統計已存在哪些介面、介面定義是什麼、執行狀態如何。
閘道器就是為了解決上述問題。作為微服務體系中的核心基礎設施,一般需要具備介面管理、協議適配、熔斷限流、安全防護等功能,各種開源的閘道器產品(比如 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 目前有兩大應用目標:
- 通用目的的 web 應用伺服器。在這個目標下,現有的 web 應用技術都可以算是和 OpenResty 或多或少有些類似,比如 Nodejs, PHP 等等。ngx_openresty 的效能(包括記憶體使用和 CPU 效率)算是最大的賣點之一。
- 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編寫指令碼,所以外掛比較豐富。
關於Kong的一些外掛庫以及如何配置,可以參考簡書:開源API網關係統(Kong教程)入門到精通:https://www.jianshu.com/p/a68e45bcadb6
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沒有本質區別,兩點變化:
- 前端用Netty Server代替Servlet,目的是支援前端非同步。後端用Netty Client代替Http Client,目的是支援後端非同步。
- 過濾器換了一下名字,用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。
幾種閘道器的對比
通俗理解光貓、閘道器、路由器、交換機區別
計算機網路°中間裝置(閘道器,路由器,交換機,網橋,中繼器,集線器)它們都可以理解為傳送或接收資料的終端裝置。
本質區分(工作網路層口不同)
傳輸層(閘道器)
網路層(路由器)
資料鏈路層(網橋,交換機)
物理層(中繼器,集線器)
參考OSI參考模型各層理解其作用區別
中繼器與集線器(HUB)
—句理解:接受,連線,擴大資訊在物理層傳播。
中繼器又叫重發器(Repeater,也叫放大器),是LAN(區域網)環境下用來延長網路距離的互連裝置中最簡單、最廉價的裝置。
**集線器(**被稱為多埠中繼器multiport repeater)是中繼器的一種形式,也稱為盒裝匯流排,所以集線器連線的計算機是共享同一物理頻寬的。正是因為這個特點,集線器不適合用來構建大型網路。
中繼器與集線器區別:1.在於連線裝置的線纜的數量。一箇中繼器通常只有兩個埠,而一個集線器通常有4至20個或更多的埠。2.集線器還有把所有節點集中在以它為中心的節點上的功能,這個叫做整合。而中繼器沒有。
集線器和中繼器兩者都屬於物理層的裝置。物理層裝置和其他層次的裝置(如:交換機、網橋、路由器Q)最大的區別在於:集線器和中繼器工作在同一個網段下的,而交換機、路由器等裝置是工作在不同網段下的。網段:指一個計算機網路中使用同一物理層裝置(傳輸介質、中繼器、集線器)能夠直接通訊的那一部分。也就是說,網際網路劃分為大大小小的網路,而一個網段只屬於網際網路中的某一個網路。
網橋與交換機
一句話理解:是集線器的升級換代產品,構建區域網,支援不同網路協議資訊傳播,提高網路資訊傳播的效能。
**網橋(Bridge)**也稱為橋接器,是連線兩個區域網的儲存轉發裝置,用它可以使完全具有相同或相似體系結構網路系統的連線,這樣不但能擴充套件網路的距離或範圍,而且可提高網路的效能、可靠性和安全性。
網橋工作在資料鏈路層9,將兩個LAN連起來,根據MAC地址來轉發幀,可以看作一個低層的路由器”(路由器工作在網路層,根據網路地址如IP地址進行轉發)。
**交換機(Switch)**是主導網路系統的集線裝置。將多個網路裝置連線起來組成一個區域網。它是一種用於電(光)訊號轉發的網路裝置,用來進行資料交換。
在計算機網路系統中,交換機是針對共享工作模式的弱點而推出的。交換機擁有一條高頻寬的背部匯流排和內部交換矩陣。交換機的所有的埠都掛接在這條背部總線上,當控制電路收到資料包以後,處理埠會查詢記憶體中的地址對照表以確定目的MAC(網絡卡的硬體地址)的NIC(網絡卡)掛接在哪個埠上,通過內部交換矩陣迅速將資料包傳送到目的埠。目的MAC若不存在,交換機才廣播到所有的埠,接收埠迴應後交換機會"學習"新的地址,並把它新增入內部地址表中。
大部分交換機工作於OSI參考模型的第二層,即資料鏈路層。交換機內部的CPU會在每個埠成功連線時,通過ARP協議學習它的MAC地址,儲存成—張ARP表。在今後的通訊中,發往該MAC地址的資料包將僅送往其對應的埠,而不是所有的埠。因此,交換機可用於劃分資料鏈路層廣播,即衝突域;但它不能劃分網路層廣播,即廣播域
通俗點說,交換機把資料包傳送到正確的位置,相當於網線,連線多個網絡卡,交換機關注資料包中的MAC地址
網橋與交換機的區別:
網橋一般分有兩個埠,而交換機具有高密度的埠。由於交換機能夠支援多個埠,因此可以把網路系統劃分成為更多的物理網段,這樣使得整個網路系統具有更高的頻寬。而網橋僅僅支援兩個埠,所以,網橋劃分的物理網段是相當有限的。
交換機與網橋資料資訊的傳輸速率相比,交換機要快於網橋。網橋在傳送資料幀前,通常要接收到完整的資料幀並執行幀檢測序列FCS後,才開始轉發該資料幀。交換機具有儲存轉發和直接轉發兩種幀轉發方式。
網橋、交換機工作在2層,靠實體地址工作,解決CSMA/CD的衝突問題,網橋基於軟體,現在用的不多,只有個概念,交換機是基於硬體的網橋(ASIC) .
路由器
一句話理解:跨越不同的物理網路型別(DDN、乙太網等等)在邏輯網路上把資料(IP報文)傳送到正確的網路。
**路由器(Router)**是一種計算機網路裝置。靠邏輯地址工作,提供邏輯定址,解決廣播問題。
提供了路由與轉送兩種重要機制。可以決定資料包從來源端到目的端所經過的路由路徑(host到host之間的傳輸路徑),這個過程稱為路由;將路由器輸入端的資料包移送至適當的路由器輸出端(在路由器內部進行),這稱為轉送。
路由工作在OSI模型的第三層——即網路層,例如網際協議。路由器的一個作用是連通不同的網路,另一個作用是選擇資訊傳送的線路。
交換機把資料包傳送到正確的位置,相當於網線,連線多個網絡卡,交換機關注資料包中的MAC地址
交換器與路由器區別:
1、本質區別
閘道器這種裝置它主要是用來連線兩種不同的網路,同時,閘道器它還能夠同時與兩邊的主機之間進行通訊。但是兩邊的主機是不能夠直接進行通訊,是必須要經過閘道器才能進行通訊。閘道器的工作是在應用層當中。
路由器它是屬於網路層裝置,通常是以包為單位進行資料的傳送。在路由器的子介面,是有分割廣播域的作用,所以當我們用交換機做VLAN以後,都是要在路由器上做一個三層的路由。
2、使用方式的區別
閘道器它可以是路由器,交換機或者是PC。在同一網段之內進行通訊,是不需要將閘道器介入其中,只有當主機個非本網段裝置進行通訊的時候,才需要將資料包全部發給閘道器裝置,再經由閘道器裝置進行轉發或者是有路由處理等。
路由器它是一個網路層系統,路由器在現在市場上一般是被分成了兩大類,一類是單協議路由器,另—類是多協議路由器。路由器它可以進行資料格式的轉換,成為不同於協議之間的網路互連的必要裝置。
3、功能上的區別
閘道器可以分為傳輸型閘道器和應用型閘道器,它的功能是充當轉換重任,實質上就是一個網路通向其他網路的IP地址。
路由器的功能主要有:連通不同的網路和資訊傳輸作用。按照使用可分為:接入、企業級、骨幹級、太位元、多WAN以及3G無線等。
閘道器
再說閘道器之前,先說一下子網的劃分,為何要劃分,因為tcp/IP協議規定,不同子網之間不能直接進行通訊,想要通訊必須要閘道器進行連線,閘道器可以在兩個子網之間轉發資料包
閘道器(Gateway),閘道器顧名思義就是連線兩個網路的裝置,區別於路由器(由於歷史的原因,許多有關TCP/IP的文獻曾經把網路層使用的路由器(Router)稱為閘道器,在今天很多區域網採用都是路由來接入網路,因此現在通常指的閘道器就是路由器的IP),經常在家庭中或者小型企業網路中使用,用於連線區域網和Internet。閘道器也經常指把一種協議轉成另一種協議的裝置,比如語音閘道器。
在傳統TCP/IP術語中,網路裝置只分成兩種,一種為閘道器(gateway),另一種為主機(host)。閘道器能在網路間轉遞資料包,但主機不能轉送資料包。在主機(又稱終端系統,end system)中,資料包需經過TCPIP四層協議處理,但是在閘道器(又稱中介系統,intermediate system)只需要到達網際層(Internet layer),決定路徑之後就可以轉送。在當時,閘道器(gateway)與路由器(router)還沒有區別。
在現代網路術語中,閘道器(gateway)與路由器(router)的定義不同。閘道器(gateway)能在不同協議間移動資料,而路由器(router)是在不同網路間移動資料,相當於傳統所說的IP閘道器(IP gateway)
閘道器是連線兩個網路的裝置,對於語音閘道器來說,他可以連線PSTN網路和乙太網,這就相當於VOIP,把不同電話中的模擬訊號通過閘道器而轉換成數字訊號,而且加入協議再去傳輸。在到了接收端的時候再通過閘道器還原成模擬的電話訊號,最後才能在電話機上聽到。
對於乙太網中的閘道器只能轉發三層以上資料包,這一點和路由是一樣的。而不同的是閘道器中並沒有路由表,他只能按照預先設定的不同網段來進行轉發。閘道器最重要的一點就是埠對映,子網內使用者在外網看來只是外網的IP地址對應著不同的埠,這樣看來就會保護子網內的使用者。
光貓:又稱調製調解器,它主要為了訊號轉換,如把模擬訊號轉換成數字訊號。