全部產品
Search
文件中心

API Gateway:後端路由

更新時間:Jul 13, 2024

Routing外掛程式具備根據請求的參數取值與系統參數取值,變更後端地址、路徑、參數或類型的能力。可以用於租戶路由,藍綠髮布,不同環境的區分等場合。

1. 概述

Routing外掛程式具備根據請求的參數取值與系統參數取值,變更後端地址、路徑、參數或類型的能力。可以用於租戶路由,藍綠髮布,不同環境的區分等場合。

1. 配置方式

1.1 配置模板

可以選擇JSON或者YAML格式的來配置您的外掛程式,兩種格式的schema相同,可以搜尋yaml to json轉換工具來進行配置格式的轉換,yaml格式的模板見下表。

---
routes:
# 當調用方的AppId為"123456"時, 路由至獨立的地址, 例子中指定了VPC授權名為"slbAddressForVip"的地址
- name: Vip
  condition: "$CaAppId = 123456"
  backend:
    type: "HTTP-VPC"
    vpcAccessName: "slbAccessForVip"
# 針對太老的用戶端, 返回不再支援的應答, ClientVersion是API中的自訂參數
- name: MockForOldClient
  condition: "$ClientVersion < '2.0.5'"
  backend: 
    type: "MOCK"
    statusCode: 400
    body: "This version is not supported!!!"

配置模板的根對象為routes,包含多個route對象,每個route對象用於指定一條路由,每條路由由以下幾個部分組成:

  • name: 表示這個路由的名稱,大小寫英文字母和數字,在每個外掛程式中保持唯一,如果命中了這條路由,後端收到的請求會包含一個名為X-Ca-Routing-Name的HTTP頭,指示本次命中的路由名稱

  • condition:路由的條件運算式,條件運算式的規範見本文2.2節中的描述,如果當前的請求符合條件運算式,則本條路由命中,Routing外掛程式會按照外掛程式的配置順序從上到下進行判斷,並將請求路由給命中的第一條記錄,並忽略後面的記錄,如果您配置了多條路由記錄,請仔細檢查配置的順序與您期望的邏輯一致。

  • backend: 後端描述,與API Gateway的Swagger標準保持一致,後端在原有API的後端上覆蓋backend配置後處理,如果覆蓋後的backend不完整,會提示用戶端X-Ca-Error-Code: I504RB,當看到這個錯誤時,請檢查自己的backend配置是否完整,關於Backend描述,請參照2.3節,Routing外掛程式中的Backend覆蓋規則

  • constant-parameters: 可以自行設定路由的常量參數,常量參數會附加在命中路由的後端請求上,用於後端的商務邏輯處理,location支援headerquery

1.2. Condition條件運算式

1.2.1 基本文法

  • Condition運算式與SQL運算式類似,基礎資料表達形式為$A = 'A' and '$B = 'B'

  • 參數以$開頭,可以引用在API中定義的參數(API為映射與透傳方式均可),如果您在API中定義了名為query1的參數,則$query1可以表示當前請求中的query1參數s

  • 支援以下常量類型:

    • STRING: 字串類型,支援單引號或雙引號,如: "Hello"

    • INTEGER: 整數類型,如:1001,-1

    • NUMBER: 浮點數類型,如: 0.1, 100.0

    • BOOLEAN: 布爾類型,如:true、false

  • 可以使用andor來串連不同的運算式

  • 可以用小括弧()來指定條件判斷的優先順序

  • 可以使用 $CaAppId 形式來引用當前請求的系統參數,系統參數不需要API中被定義即可引用,但如果您在API中定義了重名的參數,取到的值會被自訂參數覆蓋,可用於路由外掛程式的系統參數列表如下:

    • CaStage: 當前API請求的環境,RELEASE,PRE,TEST

    • CaDomain: 當前請求的網域名稱

    • CaRequestHandleTime:請求處理的UTC時間

    • CaAppId:請求參數的AppId

    • CaAppKey:請求參數的AppKey

    • CaClientIp:用戶端IP

    • CaApiName:建立時候的API名字

    • CaHttpScheme:請求的協議HTTP,HTTPS

    • CaClientUa: 用戶端上傳的UserAgent欄位

  • 如果運算式中使用了不存在的參數,如$UnknonwParameter = 1,則運算式的判斷會返回false

1.2.2 條件運算式範例

  • 當前API請求的是測試環境

    $CaStage = 'TEST'

  • 自訂參數中的UserName是Admin且來源IP是47.47.XX.XX

    $UserName = 'Admin' and $CaClientIp = '47.47.XX.XX'

  • 當前請求的使用者ID是1001,1098,2011中的一個,且使用HTTPS協議請求

    $CaHttpScheme = 'HTTPS' and ($CaAppId = 1001 or $CaAppId = 1098 or $CaAppId = 2011)

1.3. Backend的定義與覆蓋規則

Backend的結構與API Gateway匯入Swagger時的結構一致,詳細請參考文檔匯入API Gateway的擴充Swagger定義,目前支援的後端類型及配置範例如下,如果外掛程式中不需要變更後端類型,只需要變更部分設定,則不需要填寫完整的欄位,僅填寫需要變更的即可。

重要
  • HTTP

---
backend:
  type: HTTP
  address: "http://10.10.100.2:8000"
  httpTargetHostName: "a.b.com"  # 指定API Gateway請求後端的網域名稱頭(Host),優先順序最高
  path: "/users/{userId}"
  method: GET
  timeout: 7000
  • HTTP-VPC

---
backend:
  type: HTTP-VPC
  vpcAccessName: vpcAccess1
  vpcTargetHostName: "a.b.com"  # 指定API Gateway請求後端的網域名稱頭(Host),優先順序最高
  vpcScheme: "https"
  path: "/users/{userId}"
  method: GET
  timeout: 10000
  • FC

---
backend:
  type: FC
  fcRegion: cn-shanghai
  fcType: FCEvent
  serviceName: fcService
  functionName: fcFunction
  roleArn: "acs:ram::111111111:role/aliyunapigatewayaccessingfcrole"
backend:
  type: FC
  fcRegion: cn-shenzhen
  method: GET
  fcType: HttpTrigger
  fcUrl: https://1833848375796824.cn-shenzhen.fc.aliyuncs.com/2016-08-15/proxy/servicetest/fctest3/fctest3
  roleArn: acs:ram::1833848375796824:role/aliyunapigatewayaccessingfcrole
  • OSS

---
backend:
  type: OSS
  ossRegionId: cn-hangzhou
  bucketName: bucketName
  key: /objectName
  timeout: 10000
  action: putObject
  • MOCK

---
backend:
  type: MOCK
  mockResult: "mock resul sample"
  mockStatusCode: 200
  mockHeaders:
    - name: server
      value: mock
    - name: proxy
      value: GW

1.4. 權重與分發

將API的請求按權重分發到兩個不同的後端服務,權重越高的後端服務將被分發更多的請求。配置樣本如下:

---
routes:
# 配置兩個後端服務,根據後端服務承載能力不同,分別配置不同的權重,權重越高分發的請求將越多
- name: Backend01
  condition: "1 = 1"  # 1 = 1是條件命中,1 = 0是條件未命中
  weight: 100       # 用來配置後端服務流量分發權重
  backend:
    type: "HTTP"
    address: "https://test01.com"
    path: "/web/cloudapi"
- name: Backend02
  condition: "1 = 1"
  weight: 80
  backend:
    type: "HTTP"
    address: "https://test02.com"
    path: "/web/cloudapi"

重要
  • 命中一個條件,所有流量都會指向命中的後端服務

  • 命中多個條件,按權重分發流量

  • 無命中條件,所有流量都會指向API定義的後端服務

1.5. 限制

  • 外掛程式的文字大小限制為16384位元組,超過後會報錯InvalidPluginData.TooLarge

  • 單個Routing外掛程式的條數限制為160條,超過後會報錯InvalidPluginData.TooManyRoutes 當這個外掛程式綁定至共用執行個體API時只有前16條生效,綁定至專享執行個體API時全部生效

  • 單條Condition語句的大小限制為512位元組,超過後會報錯InvalidPluginData.ConditionTooLong

  • 外掛程式更新會即時生效至所有已綁定該外掛程式的API,外掛程式的更新頻率被限制為45秒一次,超出時會報錯,InvalidPluginData.UpdateTooBusy

2. 典型應用情境

2.1. 配置租戶路由(根據AppId分配不同的後端地址)

AppId為10098,10099的使用者是VIP使用者,來自這兩個使用者的請求路由到獨立的伺服器叢集去。配置樣本如下:

---
routes:
# 當調用方的AppId為10098或10099時, 路由至獨立的地址,
# 例子中指定了VPC授權名為"slbAddressForVip"的地址
- name: Vip
  condition: "$CaAppId = 10098 or $CaAppId = 10099"
  backend:
    type: "HTTP-VPC"
    vpcAccessName: "slbAccessForVip"

2.2. Stage路由(測試/預發/生產環境變更)

正式環境在阿里雲的VPC中,但希望將所有訪問測試環境的API指向公網測試伺服器。配置樣本如下:

---
routes:
# 當訪問測試環境時, 將路由轉向公網伺服器
- name: Vip
  condition: "$CaStage = 'TEST'"
  backend:
    type: "HTTP"
    address: "https://test-env.foo.com"

2.3. 藍綠髮布

將5%的流量指向一組beta伺服器位址,95%的流量指向VPC類型後端服務。配置樣本如下:

---
routes:
# 藍綠髮布情境:將5%的請求路由給藍綠髮布後端,95%的請求路由指向vpc類型後端服務。
- name: BlueGreenPercent05
  condition: "1 = 1"
  weight: 5
  backend:
    type: "HTTP"
    address: "https://beta-version.api.foo.com"
    path: "/web/cloudapi"
  constant-parameters:
  - name: x-route-blue-green
    location: header
    value: "route-blue-green"
- name: BlueGreenPercent95
  condition: "1 = 1"
  weight: 95
  backend:
    type: HTTP-VPC
    path: "/web/cloudapi"
    vpcAccessName: testvpc
說明
  • condition:1 = 1是條件命中,1 = 0是條件未命中。

  • weight:用來配置後端服務流量分發權重。

2.4 一致性雜湊演算法路由

一致性雜湊演算法根據不同的雜湊因子將訪問請求均勻地分配到後端服務。相同雜湊因子計算結果的請求,將會調度到相同的後端服務。

後端路由外掛程式支援如下雜湊因子:

  • 源IP雜湊:根據請求的源IP地址進行雜湊計算。相同源IP的請求會分發到同一台後端伺服器。

  • 參數雜湊:根據請求的參數進行雜湊計算。相同參數的請求會分發到同一台後端伺服器。

源IP雜湊的樣本如下:

---
parameters:
  clientIp: "System:CaClientIp"  
routeByHash: clientIp   #指定雜湊因子
routes:
- name: route1
  condition: "1 = 1"  # 1 = 1是條件命中,1 = 0是條件未命中
  backend:
    type: "MOCK"
    statusCode: 200
    mockResult: "Hello World!!!"
- name: route2
  condition: "1 = 1"
  backend:
    type: "MOCK"
    statusCode: 400
    mockResult: "mock resul sample"
- name: route3
  condition: "1 = 0"
  backend:
    type: "HTTP"
    address: "https://test.com"
  constant-parameters:
  - name: x-route-by-hash
    location: header
    value: "route-by-hash"