微服務網關選型:5 種主流 API 網關,哪個最香!

微服務近幾年非常火,圍繞微服務的技術生態也比較多,比如微服務網關、Docker、Kubernetes 等。

我是於 2019 年開始接觸微服務網關,當時和公司的一位同事一起開發,由於技術能力有限,我只負責網關後臺,後續微服務網關的迭代,我其實沒有參與,不過後來抽空看了微服務網關前臺的代碼,所以對這套微服務網關的實現原理算是基本掌握。

最近在寫技術棧相關的文章,剛好寫到微服務網關,就把之前學習的知識進行簡單總結,同時也把市面上常用的微服務網關進行梳理,一方面便於後續技術選型,另一方面也算是給自己一個交代。下面是文章目錄:

API 網關基礎

什麼是 API 網關

API 網關是一個服務器,是系統的唯一入口。 從面向對象設計的角度看,它與外觀模式類似。

API 網關封裝了系統內部架構,爲每個客戶端提供一個定製的 API。它可能還具有其它職責,如身份驗證、監控、負載均衡、緩存、協議轉換、限流熔斷、靜態響應處理。

API 網關方式的核心要點是,所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能。通常,網關也是提供 REST/HTTP 的訪問 API。

網關的主要功能

微服務網關作爲微服務後端服務的統一入口,它可以統籌管理後端服務,主要分爲數據平面和控制平面:

API 網關選型

常用 API 網關

先簡單看一下市面上常用的 API 網關:

Nginx

Nginx 是一個高性能的 HTTP 和反向代理服務器。Nginx 一方面可以做反向代理,另外一方面可以做靜態資源服務器,接口使用 Lua 動態語言可以完成靈活的定製功能。

Nginx 在啓動後,會有一個 Master 進程和多個 Worker 進程,Master 進程和 Worker 進程之間是通過進程間通信進行交互的,如圖所示。Worker 工作進程的阻塞點是在像 select()、epoll_wait() 等這樣的 I/O 多路複用函數調用處,以等待發生數據可讀 / 寫事件。Nginx 採用了異步非阻塞的方式來處理請求,也就是說,Nginx 是可以同時處理成千上萬個請求的。

Zuul

Zuul 是 Netflix 開源的一個 API 網關組件,它可以和 Eureka、Ribbon、Hystrix 等組件配合使用。社區活躍,融合於 SpringCloud 完整生態,是構建微服務體系前置網關服務的最佳選型之一。

Zuul 的核心是一系列的過濾器,這些過濾器可以完成以下功能:

Zuul 目前有兩個大的版本:Zuul1 和 Zuul2

Zuul1 是基於 Servlet 框架構建,如圖所示,採用的是阻塞和多線程方式,即一個線程處理一次連接請求,這種方式在內部延遲嚴重、設備故障較多情況下會引起存活的連接增多和線程增加的情況發生。

Netflix 發佈的 Zuul2 有重大的更新,它運行在異步和無阻塞框架上,每個 CPU 核一個線程,處理所有的請求和響應,請求和響應的生命週期是通過事件和回調來處理的,這種方式減少了線程數量,因此開銷較小。

Spring Cloud GateWay

Spring Cloud Gateway 是 Spring Cloud 的一個全新的 API 網關項目,目的是爲了替換掉 Zuul1,它基於 Spring5.0 + SpringBoot2.0 + WebFlux(基於⾼性能的 Reactor 模式響應式通信框架 Netty,異步⾮阻塞模型)等技術開發,性能⾼於 Zuul,官⽅測試,Spring Cloud GateWay 是 Zuul 的 1.6 倍,旨在爲微服務架構提供⼀種簡單有效的統⼀的 API 路由管理⽅式。

Spring Cloud Gateway 可以與 Spring Cloud Discovery Client(如 Eureka)、Ribbon、Hystrix 等組件配合使用,實現路由轉發、負載均衡、熔斷、鑑權、路徑重寫、⽇志監控等,並且 Gateway 還內置了限流過濾器,實現了限流的功能。

Kong

Kong 是一款基於 OpenResty(Nginx + Lua 模塊)編寫的高可用、易擴展的,由 Mashape 公司開源的 API Gateway 項目。Kong 是基於 NGINX 和 Apache Cassandra 或 PostgreSQL 構建的,能提供易於使用的 RESTful API 來操作和配置 API 管理系統,所以它可以水平擴展多個 Kong 服務器,通過前置的負載均衡配置把請求均勻地分發到各個 Server,來應對大批量的網絡請求。

Kong 主要有三個組件:

Kong 採用插件機制進行功能定製,插件集(可以是 0 或 N 個)在 API 請求響應循環的生命週期中被執行。插件使用 Lua 編寫,目前已有幾個基礎功能:HTTP 基本認證、密鑰認證、CORS(Cross-Origin Resource Sharing,跨域資源共享)、TCP、UDP、文件日誌、API 請求限流、請求轉發以及 Nginx 監控。

Kong 網關具有以下的特性:

Traefik

Træfɪk 是一個爲了讓部署微服務更加便捷而誕生的現代 HTTP 反向代理、負載均衡工具。它支持多種後臺 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Rest API, file…) 來自動化、動態的應用它的配置文件設置。

重要特性:

關於 Traefik 的更多內容,可以查看官網:https://traefik.cn/

API 網關對比

上面是網關對比截圖,偷個懶,大家主要關注 Kong、Traefik 和 Zuul 即可:

下面是其它網友的思考結論,可供參考:

基於 Traefik 自研的微服務網關

這個是我司自研的微服務網關,基於 Traefik 進行開發,下面從技術選型、網關框架、網關後臺、協議轉換進行講解,絕對乾貨!

技術棧選型

網關框架

整個網關框架分爲 3 塊:

網關後臺

主要由 3 大模塊組成:

一個應用只能綁定一個服務,但是可以綁定多個插件。 通過後臺完成網關配置後,將這些配置信息生成 Config 文件,發佈到 ETCD 中,Config 文件需要遵循嚴格的數據格式,比如 Traefix 配置需要遵循官方的文件配置格式,才能被 Traefik 識別。

協議轉換模塊

hal-proxy 模塊是整個微服務網關最複雜,也是技術含量最高的模塊,所以給大家詳細講解一下。

問題引入

在講這個模塊前,我們先看下面幾個問題:

實現原理

我們還是先看一下 hal-proxy 內部有哪些模塊,首先是 Resolver 模塊,這個模塊的是什麼作用呢?這裏我簡單介紹一下,目前公司內部通過服務獲取到機器列表的方式有多種,比如 MIS 平臺、服務樹等,也就是有的是通過平臺配置的,有的是直接掛在服務樹下,無論哪種方式,我們都通過服務名,通過一定的方式,找到該服務下面所有的主機。

所以 Resolver 模塊的作用,其實就是通過服務名,找到該服務下的所有機器的 IP 和服務端口,然後持久化到內存中,並定時更新。

協議模塊就是支持不同的協議轉換,每個協議類型的轉換,都需要單獨實現,這些協議轉換,無非就是先通過機器 IP 和端口初始化 Client,然後再將數據進行轉換後,直接發送到下游的機器。

最後就是連接池,之前我們其實也用到 go 自帶的 pool 來做,但是當對 pool 數據進行更新時,需要加鎖,所以性能一直起不來,後來改成了環形隊列,然後對數據的操作全部通過原子操作方式,就實現了無鎖操作,大大提高的併發性能。 環形隊列的代碼,也給你安排上,可以直接看這篇文章 Go 語言核心手冊 - 10. 原子操作

實現邏輯

這個是 hal-proxy 的邏輯實現圖,畫了 2 天,包含所有核心對象的交互方式,這裏就不去細講,能掌握多少,靠大家自己領悟。

盡信書則不如無書,因個人能力有限,難免有疏漏和錯誤之處,如發現 bug 或者有更好的建議,歡迎批評指正,不吝感激。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/f2hepLraaqUgRKqq9ZKKsQ