網關路由

網關(Gateway)在計算機網絡中很常見,用於表示位於內部區域邊緣,與外界進行交互的某個物理或邏輯設備,譬如你家裏的路由器就是屬於家庭內網與互聯網之間的網關。

單體架構下不太強調網關的概念,爲各個單體系統的副本分發流量的負載均衡器實質上會扮演內部服務與外部請求之間的網關角色。

爲什麼微服務架構下需要網關?並且網管已然成爲微服務架構下的一種基礎設施?why?

我個人的理解是:微服務架構下,每個服務節點可能是由不同的團隊負責,都有着自己獨立的、不相同的接口,如果服務集羣缺少一個統一對外交互的代理人角色,那外部的服務消費者就必須知道所有微服務節點在集羣中的精確座標。如此一來,外部消費者就會受到服務集羣的網絡限制(服務集羣內部一般是內網通訊)、安全限制(安全策略約束)、依賴限制等諸多不便。

總得來說,微服務中網關的首要職責就是作爲統一的出口對外提供服務,將外部訪問網關地址的請求,根據適當的規則路由到內部集羣中正確的服務節點上。因此,微服務中的網關,也常被稱作”服務網關“或者”API網關"。

微服務中的網關首先應該是個路由器,在滿足此前提的基礎上,可以依據需要通過過濾器來添加額外的職能,譬如安全、認證、授權、限流、監控、緩存,等等。網關公式:

網關 = 路由器(基礎職能) + 過濾器(可選職能)

一、網關--路由器基礎職能

服務網關主要考量的是能夠支持路由的“網絡協議層次”和“性能與可用性”這兩個方面因素。

1.1 網絡協議層次

是指負載均衡中的四層流量轉發和七層流量代理。從技術實現角度來看,對於路由這項工作,負載均衡器與服務網關在實現上是沒有什麼差別的,很多服務網關本身就是基於老牌的負載均衡器來實現的,譬如基於Nginx、HAPproxy開發的Ingress Controller,基於Netty開發的Zuul 2.0等。從目的角度來看,負載均衡器與服務網關會有一些區別,具體在於前者是爲了根據均衡算法對流量進行平均的路由,後者是爲了根據請求(流量)中的某種特徵進行正確的路由。

網關必須能夠識別流量中的特徵,這意味着網關能夠支持的網絡通信協議的層次將會直接限制後端服務節點能夠選擇的服務通信方式。如果服務集羣只提供像etcd這樣直接基於TCP訪問的服務,那隻部署四層網關便可滿足,網關以IP報文中源地址、目標地址爲特徵進行路由;如果服務集羣要提供HTTP服務,那就必須部署一個七層網關,網關以HTTP報文中的URL、Header等信息爲特徵進行路由;如果服務集羣還要提供更上層的WebSocket、SOAP等服務,那就必須要求網關同樣能夠支持這些上層協議,才能從中提取到特徵。

舉個例子,以下是一段基於SpringCloud實例中要到的Netflix Zuul網關的配置,Zuul是HTTP網關,/restful/accounts/** 和 /restful/pay/** 是HTTP中的URL的特徵,而配置中的serviceId就是路由的目標服務。

routes: 
    account: 
        path: /restful/accounts/**
        serviceId: account
        stripPrefix: false
        sensitiveHeaders: "*"

    payment:
        path: /restful/pay/**
        serviceId: payment
        stripPrefix: false
        sensitiveHeaders: "*"

1.2 性能與可用性

由於網關是所有服務對外的總出口,是流量必經之地,所以網關的路由性能將導致全局的、系統性的影響。打個比方,如果經由網關時有1ms的性能損失,那整個系統所有服務的響應延遲都會增加1ms。網關的性能與它的工作模式和自身實現算法都有關係,但毫無疑問工作模式是最關鍵的因素。如果能夠採用DSR三角傳輸模式,在實現原理上就決定了性能一定會比代理模式來的強(DSR、IPTunnel、NAT、代理等這些都是網絡基礎知識)。不過,因爲今天REST和JSON-RPC等基於HTTP協議的服務接口在對外部提供的服務中佔絕對主流的地位,所以我們所討論的服務網關默認都必須支持七層路由,通常默認無法直接進行流量轉發,只能採用代理模式。在這個前提約束下,網關的性能主要取決於它們如何代理網絡請求,也即它們的網絡I/O模型。

1.2.1 網絡I/O模型

 在套接字接口抽象下,網絡I/O的出入口就是Socket的讀和寫,Socket在操作系統接口中被抽象爲數據流,而網絡I/O可以理解爲對流的操作。每一次網絡訪問,從遠程主機返回的數據會先存放到操作系統內核的緩衝區中,然後從內核的緩衝區複製到應用程序的地址空間,所以當發生一次網絡請求時,將會按順序經歷“等待數據從遠程主機到達緩衝區”和“將數據從緩衝區複製到應用程序地址空間”兩個階段,根據實現這兩個階段的不同方法,人們把網絡I/O模型總結爲兩類、五種模型:

  1. 兩類是指同步I/O異步I/O
    1. 異步I/O:訂外賣-->之後該幹嘛幹嘛-->等騎手通知。異步I/O中數據到達緩衝區後,不需要調用進程主動進行緩衝區複製數據的操作,而是複製完成後由操作系統向線程發送信號,所以是非阻塞的。
    2. 同步I/O:自己親自去飯堂打飯
  2. 五種是指在同步I/O中又劃分出
    1. 阻塞I/OBlocking I/O):自己親自去飯堂打飯,飯堂沒做好,只好等待(線程休眠),直到飯做好。這就是被阻塞。阻塞I/O是最直觀的I/O模型,邏輯清晰,也比較節省CPU資源,但缺點是線程休眠所帶來的上下文切換,這是一種需要切換到內核態的重負載操作,不應當頻繁進行
    2. 非阻塞I/O(Non-Blocking I/O):你去飯堂,發現飯還沒做好,你就回去了,然後每隔3分鐘來一次飯堂看飯是否做好,一直重複,直到飯做好。非阻塞I/O能夠避免線程休眠,對於一些很快就能返回結果的請求,非阻塞I/O可以節省切換上下文切換的消耗,但是對於較長時間才能返回的請求,非阻塞I/O反而白白浪費了CPU資源,所以目前並不太常用。
    3. 多路複用I/O(Multiplexing I/O): 多路複用I/O本質上是阻塞I/O的一種,但是它的好處是可以在同一條阻塞線程上處理多個不同端口的監聽。比如:肯德基買套餐-->幫幾個同事帶-->發現套餐還沒做好-->繼續等待-->其中某個同事的套餐好了,送回去-->然後回來繼續等待。多路複用I/O是目前高併發網絡應用的主流,它還可以細分爲select、epoll、kqueue等不同實現,這裏就不再展開了。
    4. 信號驅動I/O(Signal-Driven I/O)四種細分模型: 去飯堂,飯沒好-->跟廚師很熟,打好招呼飯好了叫你,然後返回-->接到廚師通知-->飯堂取飯返回。廚師通知就是信號,信號驅動I/O與異步I/O的區別在於“從緩衝區獲取數據”,這個步驟的處理,前者收到了通知事可以進行復制操作了,即,要你自己從飯堂拿回宿舍,在複製完成之前線程處於阻塞狀態,本質上它仍屬於同步I/O操作,而後者異步I/O收到的通知是複製操作已經完成,即,有外賣小哥把飯給你送來。
    5. 異步I/O模型 如上4對比所述

以Zuul爲例:

在Zuul 1.0時,它採用的是阻塞I/O模型來進行最經典的“一條線程對應一個連接”(Thread-per-Connection)的方式來代理流量。採用阻塞I/O模型意味着它會有線程休眠,就有上下文切換的成本,所以如果後端服務普遍屬於計算密集型(CPU Bound,可以通俗理解爲服務耗時比較長,主要消耗在CPU上)時,這種模型能夠相對節省網關的CPU資源,但如果後端服務普遍都是I/O密集型(I/O Bound,可以理解爲服務都很快返回,主要消耗在I/O上),它就會由於頻繁的上下文切換而降低性能。

Zuul 2.0版本最大的改進就是基於Netty Server實現了異步I/O模型來處理請求,大幅度減少了線程數,獲得了更高的性能和更低的延遲。根據Netflix官方給出的數據,Zuul 2.0大約要比Zuul 1.0快上20%左右。還有一些網關甚至支持自行配置,或者根據環境選擇不同的網絡I/O模型,典型代表就是Nginx,它可以支持在配置文件中指定select、poll、epoll、kqueue等併發模型。

網關的性能高低一般只會定性分析,要定量地說哪一種網關性能最高、高多少是很困難的,就像我們都認可Chrome要比IE快,但脫離了具體場景,快多少就很難說的清楚。網上也有不少關於各種網關的性能對比數據,但若脫離具體應用場景去定量地比較不同網關的性能差異還是難以令人信服,不同的測試環境和後端服務都會直接影響結果。

網絡上也有不少關於各種網關的性能對比數據,但若脫離具體應用場景去定量地比較不同網關的性能差異還是難以令人信服,不同的測試環境和後端服務都會直接影響結果。

在網關的性能方面,我們應該考慮到以下幾點:

  • 網關儘可能的輕量。在集羣的角色定位,除了安全、認證、授權、限流、監控等功能,要對網關賦能符合自己業務場景的功能時要仔細權衡,取得功能性與可用性之間的平衡,過度增加網關的功能是危險的。
  • 網關選型,儘可能選擇成熟的產品。比如:Nginx Ingress Controller、KONG、Zuul這些經過長期考驗的產品,而不能一味地只考慮性能選擇最新的產品,性能與可用性之間的平衡也需要權衡。
  • 在需要高可用的生產環境中,應當考慮在網關之前部署負載均衡器或者等價路由器(ECMP),讓那些更成熟健壯的設施(往往是硬件物理設備)去充當整個系統的入口地址,這樣網關也可以進行擴展。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章