微服務下的網關如何選擇


前言

自從換了工作以后,將近5個月沒有寫博客了,這段時間經歷一個身份的轉變,從一個核心開發轉變為了一個項目的Leader,這種感覺說不上來的,雖說是有些感悟,但是更多的是一些困惑,但是有一點是明確的,站的高度或者角度不同,有些思考是不一樣的,有這種身份轉換的,大家可以做一些交流,嘿嘿!開啟我們的正題,最近項目要從第三方外包的手中轉成自有化的形式,我們准備采用微服務的形式去做這件事。之前也想寫這個系列的話題,整好趁着這次的改造來完成這個微服務序列的文章,首先我們來介紹下網關這個組件。

為什么出現網關

微服務的架構體系中,可以簡單的看做是一個大應用拆分為多個小應用,小應用可以自成體系,可以擁有自己的數據庫、框架甚至於語言等等,各個小應用一般通過Rest接口的形式被第三方、H5或者APP去調用。這個時候必然會存在一種情況,某些頁面需要多個服務組合才能得到用戶需要的信息。舉個栗子:

在電商系統中,查看商品詳情頁,這個商品詳情頁包含商品的詳情,價格,庫存,評論等,這些數據對於后端來說位於不同的微服務系統之中,后台的系統是這樣來拆分服務的:
商品服務:負責提供商品的標題,描述,規格等。
營銷服務:負責對產品進行定價,價格策略計算,促銷價等。
庫存服務:負責產品庫存。
評價服務:負責用戶對商品的評論,回復等。

我們不做任何處理的時候,調用的時候是這樣:


該處的缺點就是前端需要調用多次服務才能拿到我們想要的數據,為了解決這個問題我們可以做一層中間的聚合層,聚合層也就是我們通常所說的BFF(Back-end for Front-end),BFF可以認為是一種適配服務,將后端的微服務進行適配(主要包括聚合裁剪和格式適配等邏輯),實現上沒太大限制,能做請求轉發和數據轉化即可,升級以后框架是這樣的,之前我們系統處於這個階段:
升級以后的框架解決了多次調用的問題,但是這里地方會存在如下幾個問題:
1.多個聚合層有很多跨橫切面的代碼是重復的,比如安全認證,日志監控,限流熔斷等,隨着時間的發展代碼變得不可維護;
2.隨着訪問量、業務的增加,兩個BFF層也滿足不了我們的業務,需要抽象更多的BFF和采用集群部署的方式;
接下來我們再次升級我們架構,如下圖:

這里我們引入的我們本章的主角網關,由於網關的加入我們可以將所有的跨橫切面的代碼通通抽象到網關層,這樣我們BFF層只需要關注服務適配的邏輯,另外也解決掉了之前業務單點、多節點的等問題,這個時候你可能又想,網關的部署也是單點了,這個時候你可以考慮在網關前掛一層NG或者F5,如果隨着業務發展網關管理的服務越來越多,也可以將網關按照業務域進行整體的拆分。
到這里你一定了解到了為什么需要網關,寫到這里我突然想到某個偉人說的一句話,沒有什么是加一個中間層解決不了的,如果有,就加兩個……,BFF也好、網關也好都是我們的中間層。

網關選型

目前市面上根據技術棧實現的不同大概有如下一些網關:


接下來我們就簡單了解下以上5個網關:
Nginx: Nginx由內核和模塊組成,內核的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查找配置文件與客戶端請求進行 URL 匹配,用於啟動不同的模塊去完成相應的工作。

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

還可以將 Lua 嵌入到 Nginx 中,從而可以使用 Lua 來編寫腳本,這樣就可以使用 Lua 編寫應用腳本,部署到 Nginx 中運行,即 Nginx 變成了一個 Web 容器;這樣開發人員就可以使用 Lua 語言開發高性能Web應用了。在開發的時候使用 OpenResty 來搭建開發環境,OpenResty 將 Nginx 核心、LuaJIT、許多有用的 Lua 庫和 Nginx 第三方模塊打包在一起;這樣只需要安裝 OpenResty,不需要了解 Nginx 核心和寫復雜的 C/C++ 模塊就可以,只需要使用 Lua 語言進行 Web 應用開發了。

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


Kong主要有三個組件:
  1. Kong Server :基於Nginx的服務器,用來接收API請求。
  2. Apache Cassandra/PostgreSQL :用來存儲操作數據。
  3. Kong dashboard:官方推薦UI管理工具,當然,也可以使用 restfull 方式 管理admin api。

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


Kong網關具有以下的特性:
  1. 可擴展性: 通過簡單地添加更多的服務器,可以輕松地進行橫向擴展,這意味着您的平台可以在一個較低負載的情況下處理任何請求;
  2. 模塊化: 可以通過添加新的插件進行擴展,這些插件可以通過RESTful Admin API輕松配置;
  3. 在任何基礎架構上運行: Kong網關可以在任何地方都能運行。您可以在雲或內部網絡環境中部署Kong,包括單個或多個數據中心設置,以及public,private 或invite-only APIs。

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

Zuul的核心是一系列的filters, Zuul 的核心是一系列的過濾器,這些過濾器可以完成以下功能:
  1. 身份認證與安全:識別每個資源的驗證要求,並拒絕那些與要求不符的請求。
  2. 審查與監控:與邊緣位置追蹤有意義的數據和統計結果,從而帶來精確的生產視圖。
  3. 動態路由:動態地將請求路由到不同的后端集群。
  4. 壓力測試:逐漸增加指向集群的流量,以了解性能。
  5. 負載分配:為每一種負載類型分配對應容量,並棄用超出限定值的請求。
  6. 靜態響應處理:在邊緣位置直接建立部分響應,從而避免其轉發到內部集群。
  7. 多區域彈性:跨越 AWS Region 進行請求路由,旨在實現 ELB(Elastic Load Balancing,彈性負載均衡)使用的多樣化,以及讓系統的邊緣更貼近系統的使用者。

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


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

Spring Cloud GetWay:Spring Cloud Gateway 是Spring Cloud的一個全新的API網關項目,目的是為了替換掉Zuul1。Gateway可以與Spring Cloud Discovery Client(如Eureka)、Ribbon、Hystrix等組件配合使用,實現路由轉發、負載均衡、熔斷等功能,並且Gateway還內置了限流過濾器,實現了限流的功能。


  Gateway基於Spring 5、Spring boot 2和Reactor構建,使用Netty作為運行時環境,比較完美的支持異步非阻塞編程。Netty使用非阻塞的IO,線程處理模型建立在主從Reactors多線程模型上。其中Boss Group輪詢到新連接后與Client建立連接,生成NioSocketChannel,將channel綁定到Worker;Worker Group輪詢並處理Read、Write事件。

Soul: Soul是一個異步的,高性能的,跨語言的,響應式的API網關。參考了Kong,Spring-Cloud-Gateway等優秀的網關后,站在巨人的肩膀上,Soul由此誕生!


Soul特征:
  1. 支持各種語言,無縫集成Dubbo,SpringCloud。
  2. 豐富的插件支持,鑒權,限流,熔斷,防火牆等等。
  3. 網關多種規則動態配置,支持各種策略配置。
  4. 插件熱插拔,易擴展
  5. 支持集群部署,支持A/B Test

總結一下:

  1. 性能
    Nginx+Lua形式必然是高於Java語言實現的網關的,Java技術棧里面Zuul1.0是基於Servlet實現的,剩下都是基於webflux實現,性能是高於基於Servlet實現的。在性能方面我覺得選擇網關可能不算那么重要,多加幾台機器就可以搞定。
  2. 可維護性和擴展性
    Nginx+Lua這個組合掌握的人不算多,如果團隊有大神,大佬們就隨意了,當沒看到這段話,對於一般團隊來說的話,選擇自己團隊擅長的語言更重要,所以我選擇了Java技術棧下的網關。Java技術棧下的3種網關,對於Zuul和Spring Cloud Getway需要或多或少要搞一些集成和配置頁面來維護,但是對於Soul我就無腦看看文章,需要哪個搬哪個好了,尤其是可以無腦對接Dubbo美滋滋,此外Soul2.0以后版本可以擺脫ZK,在我心里再無詬病,我就喜歡無腦操作。
  3. 高可用
    對於網關高可用基本都是統一的策略都是采用多機器部署的方式,前面掛一個負載,對於而外需要用的一些組件大家注意一下。

結束

歡迎大家點點關注,點點贊,感謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM