微服務下的網關如何選擇

前言

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

爲何出現網關

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

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

咱們不作任何處理的時候,調用的時候是這樣:編程


該處的缺點就是前端須要調用屢次服務才能拿到咱們想要的數據,爲了解決這個問題咱們能夠作一層中間的聚合層,聚合層也就是咱們一般所說的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 應用開發了。api

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 框架構建,如圖所示,採用的是阻塞和多線程方式,即一個線程處理一次鏈接請求,這種方式在內部延遲嚴重、設備故障較多狀況下會引發存活的鏈接增多和線程增長的狀況發生。restful


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

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


  Gateway基於Spring 五、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. 高可用
    對於網關高可用基本都是統一的策略都是採用多機器部署的方式,前面掛一個負載,對於而外須要用的一些組件你們注意一下。

結束

歡迎你們點點關注,點點贊,感謝!

相關文章
相關標籤/搜索