后端路由
Routing插件具備根據(jù)請求的參數(shù)取值與系統(tǒng)參數(shù)取值,變更后端地址、路徑、參數(shù)或類型的能力。可以用于租戶路由,藍綠發(fā)布,不同環(huán)境的區(qū)分等場合。
1. 概述
Routing插件具備根據(jù)請求的參數(shù)取值與系統(tǒng)參數(shù)取值,變更后端地址、路徑、參數(shù)或類型的能力。可以用于租戶路由,藍綠發(fā)布,不同環(huán)境的區(qū)分等場合。
1. 配置方式
1.1 配置模板
可以選擇JSON或者YAML格式的來配置您的插件,兩種格式的schema相同,可以搜索yaml to json
轉(zhuǎn)換工具來進行配置格式的轉(zhuǎn)換,YAML格式的模板見下表。
---
routes:
# 當(dāng)調(diào)用方的AppId為"123456"時, 路由至獨立的地址, 例子中指定了VPC授權(quán)名為"slbAddressForVip"的地址
- name: Vip
condition: "$CaAppId = 123456"
backend:
type: "HTTP-VPC"
vpcAccessName: "slbAccessForVip"
# 針對太老的客戶端, 返回不再支持的應(yīng)答, ClientVersion是API中的自定義參數(shù)
- name: MockForOldClient
condition: "$ClientVersion < '2.0.5'"
backend:
type: "MOCK"
statusCode: 400
body: "This version is not supported!!!"
配置模板的根對象為routes
,包含多個route
對象,每個route
對象用于指定一條路由,每條路由由以下幾個部分組成:
name: 表示這個路由的名稱,大小寫英文字母和數(shù)字,在每個插件中保持唯一,如果命中了這條路由,后端收到的請求會包含一個名為
X-Ca-Routing-Name
的HTTP頭,指示本次命中的路由名稱condition:路由的條件表達式,條件表達式的規(guī)范見本文2.2節(jié)中的描述,如果當(dāng)前的請求符合條件表達式,則本條路由命中,Routing插件會按照插件的配置順序從上到下進行判斷,并將請求路由給命中的第一條記錄,同時忽略后面的記錄,如果您配置了多條路由記錄,請仔細檢查配置的順序與您期望的邏輯一致。
backend: 后端描述,與API網(wǎng)關(guān)的Swagger標準保持一致,后端在原有API的后端上覆蓋backend配置后處理,如果覆蓋后的backend不完整,會提示客戶端
X-Ca-Error-Code: I504RB
,當(dāng)看到這個錯誤時,請檢查自己的backend配置是否完整,關(guān)于Backend描述,請參照2.3節(jié),Routing插件中的Backend覆蓋規(guī)則constant-parameters: 可以自行設(shè)置路由的常量參數(shù),常量參數(shù)會附加在命中路由的后端請求上,用于后端的業(yè)務(wù)邏輯處理,location支持
header
和query
。
1.2. Condition條件表達式
1.2.1 基本語法
Condition表達式與SQL表達式類似,基礎(chǔ)表達形式為
$A = 'A' and '$B = 'B'
參數(shù)以
$
開頭,可以引用在API中定義的參數(shù)(API為映射與透傳方式均可),如果您在API中定義了名為query1的參數(shù),則$query1
可以表示當(dāng)前請求中的query1參數(shù)s支持以下常量類型:
STRING
: 字符串類型,支持單引號或雙引號,如: "Hello"INTEGER
: 整數(shù)類型,如:1001,-1NUMBER
: 浮點數(shù)類型,如: 0.1, 100.0BOOLEAN
: 布爾類型,如:true、false
可以使用
and
、or
來連接不同的表達式可以用小括號
(
,)
來指定條件判斷的優(yōu)先級可以使用
$CaAppId
形式來引用當(dāng)前請求的系統(tǒng)參數(shù),系統(tǒng)參數(shù)不需要API中被定義即可引用,但如果您在API中定義了重名的參數(shù),取到的值會被自定義參數(shù)覆蓋,可用于路由插件的系統(tǒng)參數(shù)列表如下:CaStage: 當(dāng)前API請求的環(huán)境,
RELEASE
,PRE
,TEST
CaDomain: 當(dāng)前請求的域名
CaRequestHandleTime:請求處理的UTC時間
CaAppId:請求參數(shù)的AppId
CaAppKey:請求參數(shù)的AppKey
CaClientIp:客戶端IP
CaApiName:創(chuàng)建時候的API名字
CaHttpScheme:請求的協(xié)議
HTTP
,HTTPS
CaClientUa: 客戶端上傳的UserAgent字段
如果表達式中使用了不存在的參數(shù),如
$UnknonwParameter = 1
,則表達式的判斷會返回false
1.2.2 條件表達式樣例
當(dāng)前API請求的是測試環(huán)境
$CaStage = 'TEST'
自定義參數(shù)中的UserName是Admin且來源IP是
47.47.XX.XX
$UserName = 'Admin' and $CaClientIp = '47.47.XX.XX'
當(dāng)前請求的用戶ID是1001,1098,2011中的一個,且使用HTTPS協(xié)議請求
$CaHttpScheme = 'HTTPS' and ($CaAppId = 1001 or $CaAppId = 1098 or $CaAppId = 2011)
1.3. Backend的定義與覆蓋規(guī)則
Backend的結(jié)構(gòu)與API網(wǎng)關(guān)導(dǎo)入Swagger時的結(jié)構(gòu)一致,詳細請參考文檔導(dǎo)入API網(wǎng)關(guān)的擴展Swagger定義,目前支持的后端類型及配置樣例如下,如果插件中不需要變更后端類型,只需要變更部分設(shè)置,則不需要填寫完整的字段,僅填寫需要變更的即可。
如果使用了weight,則需要填寫完整的字段。
關(guān)于Host優(yōu)先級配置,更多詳情可以見配置后端服務(wù)Host(域名頭)。
HTTP
---
backend:
type: HTTP
address: "http://10.10.100.2:8000"
httpTargetHostName: "a.b.com" # 指定API網(wǎng)關(guān)請求后端的域名頭(Host),優(yōu)先級最高
path: "/users/{userId}"
method: GET
timeout: 7000
HTTP-VPC
---
backend:
type: HTTP-VPC
vpcAccessName: vpcAccess1
vpcTargetHostName: "a.b.com" # 指定API網(wǎng)關(guān)請求后端的域名頭(Host),優(yōu)先級最高
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. 權(quán)重與分發(fā)
將API的請求按權(quán)重分發(fā)到兩個不同的后端服務(wù),權(quán)重越高的后端服務(wù)將被分發(fā)更多的請求。配置示例如下:
---
routes:
# 配置兩個后端服務(wù),根據(jù)后端服務(wù)承載能力不同,分別配置不同的權(quán)重,權(quán)重越高分發(fā)的請求將越多
- name: Backend01
condition: "1 = 1" # 1 = 1是條件命中,1 = 0是條件未命中
weight: 100 # 用來配置后端服務(wù)流量分發(fā)權(quán)重
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"
命中一個條件,所有流量都會指向命中的后端服務(wù)
命中多個條件,按權(quán)重分發(fā)流量
無命中條件,所有流量都會指向API定義的后端服務(wù)
1.5. 限制
插件的文本大小限制為16384字節(jié),超過后會報錯
InvalidPluginData.TooLarge
單個Routing插件的條數(shù)限制為160條,超過后會報錯
InvalidPluginData.TooManyRoutes
(當(dāng)這個插件綁定至共享實例API時只有前16條生效,綁定至Serverless實例API時只有前160條生效,綁定至專享實例API時全部生效)單條Condition語句的大小限制為512字節(jié),超過后會報錯
InvalidPluginData.ConditionTooLong
插件更新會實時生效至所有已綁定該插件的API,插件的更新頻率被限制為45秒一次,超出時會報錯,
InvalidPluginData.UpdateTooBusy
2. 典型應(yīng)用場景
2.1. 配置租戶路由(根據(jù)AppId分配不同的后端地址)
AppId為10098,10099的用戶是VIP用戶,來自這兩個用戶的請求路由到獨立的服務(wù)器集群去。配置示例如下:
---
routes:
# 當(dāng)調(diào)用方的AppId為10098或10099時, 路由至獨立的地址,
# 例子中指定了VPC授權(quán)名為"slbAddressForVip"的地址
- name: Vip
condition: "$CaAppId = 10098 or $CaAppId = 10099"
backend:
type: "HTTP-VPC"
vpcAccessName: "slbAccessForVip"
2.2. Stage路由(測試/預(yù)發(fā)/生產(chǎn)環(huán)境變更)
正式環(huán)境在阿里云的VPC中,但希望將所有訪問測試環(huán)境的API指向公網(wǎng)測試服務(wù)器。配置示例如下:
---
routes:
# 當(dāng)訪問測試環(huán)境時, 將路由轉(zhuǎn)向公網(wǎng)服務(wù)器
- name: Vip
condition: "$CaStage = 'TEST'"
backend:
type: "HTTP"
address: "https://test-env.foo.com"
2.3. 藍綠發(fā)布
將5%的流量指向一組beta服務(wù)器地址,95%的流量指向VPC類型后端服務(wù)。配置示例如下:
---
routes:
# 藍綠發(fā)布場景:將5%的請求路由給藍綠發(fā)布后端,95%的請求路由指向vpc類型后端服務(wù)。
- 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:用來配置后端服務(wù)流量分發(fā)權(quán)重。
2.4 一致性哈希算法路由
一致性哈希算法根據(jù)不同的哈希因子將訪問請求均勻地分配到后端服務(wù)。相同哈希因子計算結(jié)果的請求,將會調(diào)度到相同的后端服務(wù)。
后端路由插件支持如下哈希因子:
源IP哈希:根據(jù)請求的源IP地址進行哈希計算。相同源IP的請求會分發(fā)到同一臺后端服務(wù)器。
參數(shù)哈希:根據(jù)請求的參數(shù)進行哈希計算。相同參數(shù)的請求會分發(fā)到同一臺后端服務(wù)器。
源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"