標籤:壓縮 回調 重要 雙向 ros net 中斷 規模 配置路由
公眾號:聊聊架構
5 月 21 日,Netflix 在其官方部落格上宣布正式開源微服務網關組件 Zuul 2。Netflix 公司是微服務界的楷模,他們有大規模生產級微服務的成功應用案例,也開源了相當多的微服務元件(詳見 GitHub 首頁),受到了業內同行的高度認可。Zuul 是 Netflix 於 2013 年 6 月 12 日開源的網關組件,目前在 GitHub 已經有超過 4000 個關注,包括 Riot、攜程、拍拍貸等公司都已經在生產環境中使用。
Zuul 在英文中是一種怪獸,星際爭霸中蟲族裡頭也有 Zuul,Netflix 為網關起名 Zuul,寓意看門神獸。2013 年左右,InfoQ 曾經對前 Netflix 架構總監 Adrian Cockcroft 有過一次專訪,其中有問 Adrian:“Netflix 開源這麼多項目,你認為哪一個是最不可或缺的 (MOST Indispensable)”,Adrian 回答說:“在 NetflixOSS 開源項目中,有一個容易被忽略,但是 Netflix 最強大的基礎服務之一,它就是 Zuul 網關服務。Zuul 網關主要用於智能路由,同時也支援認證,地區和內容感知路由,將多個底層服務彙總成統一的對外 API。Zuul 網關的一大亮點是動態可程式化,配置可以秒級生效”。從 Adrian 的回答中,我們可以感受到 Zuul 網關對微服務基礎架構的重要性。
因為 Zuul 開源時間較早,在架構方面也存在一些問題,所以在 2016 年 9 月,Netflix 對外宣布他們將會調整 Zuul 的架構。Zuul 原本採用同步阻塞架構,轉型後叫作 Zuul 2,採用非同步非阻塞架構。Zuul 2 和 Zuul 1 在架構方面的主要區別在於,Zuul 2 運行在非同步非阻塞的架構上,比如 Netty。Zuul 1 依賴多線程來支援輸送量的增長,而 Zuul 2 使用的 Netty 架構依賴事件迴圈和回呼函數。
下面是 Netflix 官方部落格中對於 Zuul 2 的介紹,供讀者參考。
Netflix 的 Cloud Gateway 團隊運行並維護著 80 多個 Zuul 2 叢集,將流量分發到大約 100 個(還在不斷增長)後端服務叢集,每秒的請求數超過 100 萬個。所有這些流量幾乎都來自啟用了大家熟悉的發現和回放體驗的用戶端裝置和瀏覽器。
本文將詳細介紹 Netflix 今天發布的 Zuul 2 的一些有趣特性,並討論我們正在使用 Zuul 2 構建的其他一些項目。
Zuul 2 的工作原理
以下是 Zuul 2 的大體架構圖:
過濾器前端和後端的 Netty 事件處理器(handler)主要負責處理網路通訊協定、Web 服務器、串連管理和代理工作。這些內部工作被抽象之後,所有主要的工作都會交給過濾器完成。入站過濾器在代理請求之前運行,可用於驗證、路由或裝飾請求。端點過濾器可用於返回靜態響應,或將請求代理到後端服務。出站過濾器在返迴響應後運行,可用於諸如壓縮(gzipping)、指標或增刪自訂要求標頭之類的內容。
Zuul 的功能幾乎完全取決於每個過濾器的邏輯。這意味著它可以部署在多種上下文中,使用配置和啟動並執行過濾器解決不同的問題。
我們在所有外部流量進入 Netflix 雲端服務的入口處都會使用 Zuul,並且也開始使用它來路由內部流量。Zuul用作外部流量網關和內部流量網關時,Zuul的核心架構是一樣的,只是用作內部流量網關時實現相應功能的過濾器要少很多。
正式開源
今天啟動並執行 Zuul 代碼是 Zuul 最穩定和最有彈性的版本。經過多個階段的程式碼程式庫演化和重構,我們無比高興將它分享給你們。
今天我們將發布許多核心特性。以下是最讓人激動的:
伺服器協議
彈性特性
運營特性
請求 Passport——跟蹤每個請求的所有生命週期事件,這對調試非同步請求非常有用
狀態分類——請求成功和失敗的可能狀態枚舉,比 HTTP 狀態代碼更精細
請求嘗試——跟蹤每個代理的嘗試和狀態,對調試重試和路由特別有用
我們也在研究一些即將推出的功能,包括:
Websocket/SSE——支援通道推播通知
限流和限速——防止惡意用戶端串連和請求,協助抵禦大規模攻擊
掉電過濾器——Zuul 過載時禁用一些 CPU 密集型特性
可配置路由——基於檔案的路由配置,而不需要在 Zuul 中建立路由過濾器
Zuul 2 在 Netflix 的應用
在 Netflix,幾個主要特性我們一直在研究,但尚未開源。每一個都值得專門寫一篇博文介紹,但是我們現在只簡單介紹一下。
自助服務路由
我們的夥伴使用最廣泛的特性是自助服務路由。我們為使用者提供應用程式和 API,以根據請求 URL、路徑、查詢參數或要求標頭中的任何條件建立路由規則。然後,我們將這些路由規則發布到所有 Zuul 執行個體。
主要的用例是將流量路由到特定的測試或臨時叢集。但是,實際生產流量有很多用例。例如:
需要分割流量的服務會建立路由規則,將某些路徑或首碼映射到不同的源
通過建立新主機名稱映射到新的源的路由,開發人員上線新服務
開發人員運行負載測試,將一定比例的現有流量路由到小型叢集,並確保應用程式在負載情況下會優雅地服務降級
通過逐步建立映射流量的規則,一次一條路徑,重構應用程式的團隊可以逐漸遷移到新的源
團隊通過向運行新版本的插樁群集(instrumented cluster)發送一小部分流量來測試變更(金絲雀測試)
如果團隊測試的變更需要多次連續請求新版本,他們將運行 Sticky 金絲雀測試,短時間內將同一批使用者路由到新版本
安全團隊建立基於路徑或要求標頭的規則,拒絕所有 Zuul 叢集中的“惡意”請求
正如你所看到的,我們廣泛地使用自助服務路由,並且在增加路由的可定製性和範圍,以支援更多的用例。
彈性負載平衡
我們一直在努力的另一個主要特性是,使負載平衡更加智能化。我們能夠繞過運行大量節點時經常出現的故障、緩慢、GC 問題以及各種其他問題。這個特性的目標是提高所有 Netflix 服務的彈性、可用性和服務品質。
以下是我們處理的幾個案例:
冷執行個體
當新的源執行個體啟動時,一段時間內,我們會將它們的流量減少,直到它們變熱。在具有大型程式碼程式庫和使用巨大的中繼資料空間的應用程式中,我們觀察到了這個問題。這些應用需要花費大量的時間來解釋(JIT)代碼並準備好處理大量的流量。
如果碰巧命中影響速度的冷卻的執行個體,我們通常還會將流量偏向較舊的執行個體,我們總是可以重試熱的執行個體。這使我們在可用性方面有了一個數量級的提高。
高錯誤率
由於各種原因,錯誤總是發生,無論是由於代碼中的錯誤、錯誤的執行個體還是設定了無效的配置屬性。幸運的是,作為代理,我們可以可靠地檢測錯誤——無論是 5xx 錯誤還是服務串連問題。
我們跟蹤每個源的錯誤率,如果錯誤率很高,這意味著整個服務都有問題。我們限制裝置的重試次數並禁用內部重試,以便服務恢複。此外,我們還會追蹤每個執行個體的連續失敗並在一段時間內將失敗的執行個體列入黑名單。
過載執行個體
通過上述方法,我們向叢集中限流或拒絕已連線的服務器發送較少的流量,並通過在其他伺服器上重試這些失敗請求來減輕影響。
我們現在正推出一個額外的方法,目標是一開始就避免伺服器過載。這是通過讓源向 Zuul 發送它們當前的利用率來實現的,Zuul 然後將利用率用作其負載平衡選擇中的一個因子——從而降低錯誤率、重試和延遲。
源為所有響應添加要求標頭,說明其百分比利用率,以及期望的整個叢集的目標利用率。計算百分比利用率完全取決於每個應用程式,工程師可以使用最適合他們的任何指標。與我們提出一種通用的方法相比,這可以提供一個一般的解決方案。
通過這個特性,我們為每個執行個體分配一個分數(執行個體利用率和其他因素的組合),並進行二選一負載平衡選擇。
異常檢測和上下文警告
隨著我們從少數幾個源發展到任何人都可以快速啟動一個容器叢集並將其部署在 Zuul 後面,我們發現需要自動檢測並確定源的故障。
得益於 Mantis 即時事件流,我們構建了一個異常檢測器,匯總每項服務的錯誤率,並在服務出現問題時即時通知我們。它根據給定的時間視窗內所有異常,建立一個所有有問題的源的時間表。然後,我們建立一個包含內容相關的警報電子郵件,其中包含事件時間表和受影響的服務。這使得營運人員可以快速關聯這些事件並釐清思路,調試特定的應用程式或功能,並最終找到根本原因。
事實上,發送通知給源團隊本身非常有用。除 Zuul 之外,我們還添加了更多內部應用程式,可以構建更為廣泛的事件時間表。這在生產事故中提供了巨大協助,協助營運人員在發生嚴重中斷之前迅速發現並解決問題。
原文地址:https://medium.com/netflix-techblog/open-sourcing-zuul-2-82ea476cb2b3
Netflix正式開源其API GatewayZuul 2--轉