測試開發:從0到1學習如何測試API閘道器

狂師發表於2021-05-27

本文來自我的一名學員分享

日常工作中,難免會遇到臨危受命的情況,雖然沒有這麼誇張,但是也可能會接到一個陌生的任務,也許只是對這個概念有所耳聞。也許這個時候會感到一絲的焦慮,生怕沒法完成領導交給的測試任務。其實也沒有必要那麼緊張,面對一個陌生的被測物件,我們只需要去了解清楚它的應用場景、內部原理、實現邏輯,結合開發的設計需求,一樣也能完成好測試任務,積累經驗。這次就分享一些從0到1學習如何測試API閘道器的經驗。

一、什麼是API閘道器

簡述:

API閘道器出現的原因是微服務架構的出現,不同的微服務一般會有不同的網路地址,而外部的客戶端可能需要呼叫多個服務的介面才能完成一個業務需求,這個時候系統結構會顯得非常錯綜複雜,會出現許多問題:

  • 客戶端複雜性增加,現在一般同一套後端服務會支撐多個客戶端
  • 存在跨域請求,在一定場景下處理相對複雜
  • 認證複雜,每個服務都需要單獨驗證
  • 耦合度高,難以重構
  • 某些微服務會存在防火牆等一些保護措施,無法直接訪問

微服務閘道器是微服務架構中的一個關鍵角色,用來保護,增強和控制對於微服務的訪問,微服務閘道器是一個處於應用程式或服務之前的系統,用來管理授權,訪問控制和流量限制等,這樣微服務就會被微服務閘道器保護起來對所有的呼叫者透明。因此,隱藏在微服務閘道器後面的業務系統就可以更加專注於業務本身。

組成:

  • 路由轉發:接受外界請求,轉發到後端微服務
  • 過濾器:完成一系列橫切功能,例如許可權校驗,限流以及監控等

優點:

  • 安全性高,只有閘道器係統對外進行暴露,微服務可以隱藏在內網,通過防火牆策略保護
  • 易於監控,可以在閘道器收集監控資料並將其推送到外部監控系統進行分析
  • 易於認證,可以在閘道器處統一進行認證,無需在後端微服務中進行認證
  • 減少耦合,避免多個客戶端與後端微服務之間的互動次數
  • 易於鑑權,在閘道器處統一鑑權

職能:

  • 請求接入,作為所有API介面服務請求的接入點
  • 業務聚合,作為所有後端業務服務的聚合點
  • 中介策略,實現安全,驗證,路由,過濾,流控等策略
  • 統一管理,對所有API服務和策略進行統一管理

二、微服務閘道器常見技術

  • nginx是一個高效能的HTTP和反向代理web伺服器,同時也提供了IMAP/POP3/SMTP服務
  • zuul,Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器
  • spring-cloud-gateway是spring出品的基於spring的閘道器專案,整合斷路器,路徑重寫等,效能比Zuul好

2.1 gateway是什麼

Spring Cloud Gateway旨在為微服務架構提供一種簡單而有效的統一的API路由管理方式。Spring Cloud Gateway作為Spring Cloud生態系中的閘道器,目標是替代Zuul,其不僅提供統一的路由方式,並且基於Filter鏈的方式提供了閘道器基本的功能,例如:安全,監控/埋點,和限流等。

幾個概念

  • Route(路由):這是閘道器的基本構建塊。它由一個ID,一個目標URI,一組斷言和過濾器定義。如果斷言為真,則路由匹配成功。
  • Predicate(斷言):輸入型別是一個ServerWebExchange。我們可以使用它來匹配來自HTTP請求的任何內容,例如headers或引數。
  • Filter(過濾器):Gateway中的Filter分為兩種型別的filter,分別是gateway filter和global filter,過濾器會對請求和響應作處理。

2.2 gateway怎麼用

說到底predicate就是為了實現一組匹配規則,方便讓請求過來找到對應的Route進行處理,而spring cloud gateway內建了幾種predicate的使用。

1、通過時間匹配

Predicate 支援設定一個時間,在請求進行轉發的時候,可以通過判斷在這個時間之前或者之後進行轉發。比如我們現在設定只有在 2018 年 1 月 20 日才會轉發到我的網站,在這之前不進行轉發,我就可以這樣配置:

spring:
  cloud:
    gateway:
      routes:
       - id: time_route
        uri: http://youknowit.com
        predicates:
         - After=2018-01-20T06:06:06+08:00[Asia/Shanghai]

2、通過cookie匹配

Cookie Route Predicate 可以接收兩個引數,一個是 Cookie name , 一個是正規表示式,路由規則會通過獲取對應的 Cookie name 值和正規表示式去匹配,如果匹配上就會執行路由,如果沒有匹配上則不執行。

spring:
  cloud:
    gateway:
      routes:
       - id: cookie_route
         uri: http://youknowit.com
         predicates:
         - Cookie=youknowit, value

3、通過請求路徑匹配

Path Route Predicate 接收一個匹配路徑的引數來判斷是否走路由。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://x.x.x.x:8022/
        predicates:
        - Path=/foo/{segment}

如果請求路徑符合要求,則此路由將匹配,例如:/foo/1或者/foo/bar。

當然內建的匹配規則還有很多,通過請求引數,請求方式,請求IP地址等去匹配,也可以組合使用。

注意:

一個請求滿足多個路由的謂詞條件時,請求只會被首個成功匹配的路由轉發

本次提測版本,開發使用spring-cloud-gateway來將平臺業務側引入閘道器, 將閘道器作為呼叫PaaS的唯一入口,便於維護,同時利用閘道器的能力實現限流,熔斷,鑑權,灰度驗證等功能。第一期只接入統一前裝,充分驗證後後續接入其他應用。因此,本次測試的重點在路由轉發功能。

三、常見測試點

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 5000
        response-timeout: 5s
        ssl:
          close-notify-flush-timeout-millis: 3000
          close-notify-read-timeout-millis: 0
          handshake-timeout-millis: 10000
          useInsecureTrustManager: true
      routes:
        # gis
        - id: gis_route
          predicates:
            - Path=/gis/**
          uri: http://x.x.x.x:8022/

知道了閘道器的基礎知識和基本原理之後,對於我們如何測試它,作為一名測試人員心中已經有了大概的思路,接下來就是根據我們實際的需求去列出測試點,並進一步轉換為用例去執行。從上面開發給出的配置能知道,此次開發提測主要是實現了基於路徑匹配的路由轉發功能,其餘功能暫未引入,這樣想來就簡單了許多。

3.1 功能測試

常見請求正常轉發

  • get請求正常轉發:帶引數與不帶引數
  • post請求正常轉發:資料格式校驗,例如json,form等
  • delete請求正常轉發:帶引數與路徑帶參
  • put請求正常轉發:資料格式校驗,例如json,form等
  • patch請求正常轉發:資料格式校驗,例如json,form等
  • 介面超時測試:具體的邊界值測試需根據自身業務需求場景來設計case
  • 檔案上傳功能:大小限制,亂碼問題,格式問題
  • 路由規則:根據專案需求的不同規則來制定,例如全量匹配,正則,先後順序等
  • 負載策略:輪詢,權重等
  • 超時設定

3.2 外掛測試

API閘道器外掛各個公司根據不同的需求有不同的外掛,此次提測也沒有涉及,所以收集整理了一些常見的通用外掛,例如降級,限流,熔斷,跨域,abtest外掛等,提供一些測試思路。

限流

基本概念: 客戶端請求太多,超出了服務端的承受能力,導致服務端不可用或無法響應,耗盡服務端資源甚至是服務崩潰。解決方案:服務端對客戶端進行限流,保護服務端資源。對各類請求設定最高的QPS閾值,當請求高於閾值時直接阻斷。

限流外掛測試思路:可以在API閘道器平臺為對應測試介面配置限流策略。根據不同時間,使用壓測工具進行階段性的壓力測試,並統計阻斷介面數,具體的數值可以根據自身業務場景進行測試。

降級

基本概念: 服務降級是指當伺服器壓力劇增的情況下,根據實際業務情況,將一些不重要的介面換種簡單的方式處理,從而將伺服器資源釋放給當前的核心業務使其可以高效運作。

降級外掛測試思路:降級策略主要看開發如何選擇,有的就是讓請求無法訪問到後端服務,藉口暫停使用,當介面配置降級外掛。外掛開關開啟,返回API閘道器所配置的響應資訊狀態碼等,介面是無法真正的請求到後端服務。

熔斷

基本概念: 微服務架構中,各個微服務之間相互依賴非常普遍,因此在整個鏈路中 ,有一個環節出現問題,都會造成整個上下游服務呼叫出現問題,服務出現當機。也就是說,熔斷就是呼叫方發起服務呼叫時,如果被呼叫方返回的錯誤率超過一定的閾值,那麼後續的請求不會真正發起請求,而是呼叫方直接返回錯誤。兩個關鍵點,判斷何時熔斷和何時從熔斷狀態恢復。

熔斷外掛測試思路: 不同的閘道器有不同的熔斷策略,例如針對5xx的返回,根據不同的入參控制返回,可返回2xx,4xx,5xx,當規定的時間5xx數達到閾值,服務是否開啟熔斷。熔斷恢復測試也是一樣,比如10s,允許部分請求通過,你可以繼續控制請求,若這部分請求都成功,恢復熔斷。具體的case設計還是要根據自身業務為準。

跨域

基本概念: 跨域是指,只要協議,域名,埠有任何一個不相同,都被當作是不同的域。所謂同源策略就是指,協議,域名和埠都要相同,其中有一個不同都會產生跨域。

跨域測試思路: CORS是一種基於HTTP頭的機制,該機制通過允許伺服器標識除了自己以外的其他origin,這樣瀏覽器可以訪問載入這些資源。瀏覽器必須首先使用OPTIONS方法發起一個預檢請求,從而獲知服務端是否允許該垮源請求。伺服器允許之後,才發起實際的HTTP請求。在預檢請求的返回中,服務端也可以通知客戶端,是否需要攜帶身份憑證。測試時,我們就可以通過是否需要攜帶引數,身份憑證等;各種引數組合,不同請求等方面去設計case。

3.3 容錯測試

  • 資料庫當機或者重啟:新發布的路由或者外掛設定等資料操作可能失敗,但是不影響已生效的路由和外掛
  • 後端服務其中一臺或多臺當機,重啟,新增新節點等:負載策略能夠自動提出不可用的服務節點和自動增加新的服務節點
  • redis服務當機一臺或多臺:不影響已生效路由和外掛
  • eureka掛一臺或多臺:不影響已生效負載策略

注意: 資料庫down,因為有本地快取,驗證本地快取是否生效,所以資料庫重啟或者down掉,不能影響已經生效的路由和外掛;後端服務down掉一臺,驗證eureka是否有將死掉的節點刪除,若eureka並沒有將死掉的節點刪除,則會報錯。新增新的節點,需要看請求是否有輪詢;redis主要用於限流,在redis down掉限流策略失效,但是其他外掛功能及路由應該不受影響;eureka是註冊中心,註冊中心在啟動的時候會將所有資源載入本地,所以eureka掛一臺或者多臺,不影響已經載入到本地的。
總上所述,總結來說就是API閘道器的所有依賴都可以down,但是gateway不可以不用。

3.4 壓力測試

  • 正常壓測:壓API閘道器的API即可
  • 負載測試:壓測時,增加和減少後端服務節點;某個服務資源打滿或者超時嚴重,不影響其他專案正常訪問
  • 切換路由配置
  • 專案資源測試:超過配置資源返回錯誤
  • ...

注意: 專案資源的作用是進行執行緒隔離,每個專案資源分配應該是固定的,不能搶佔其他專案資源而導致其他服務不可用,進行負載測試時,增加壓力,增加和減少後端服務節點,請求應該不報錯。

四、總結

上述內容,是對一些閘道器通用功能的測試思路總結。由於本次開發提測閘道器版本並沒有涉及過多的功能,例如還有叢集的熱載入,外掛在叢集專案與API間的運用,API的釋出,下線,外掛的隨時切換,監控等需求,親身實踐還不夠,只能提供一些思路,還需要具體結合專案的業務進行更為準確的case設計。

相關文章