HTTP 路由
Envoy 包含一個 HTTP 路由過濾器,可以安裝它來執行進階路由任務。
這對於處理邊緣流量(傳統的反向代理請求處理)以及建構服務到服務的 Envoy 網格(通常透過路由到主機/授權 HTTP 標頭以到達特定的上游服務叢集)都很有用。
Envoy 還可以設定為轉發代理。在轉發代理設定中,網格客戶端可以透過將其 HTTP 代理適當地設定為 Envoy 來參與。
在高階層次上,路由器會接收傳入的 HTTP 請求,將其匹配到上游叢集,取得連線到上游叢集中的主機的連線集區,然後轉發請求。
路由器過濾器支援許多功能,包括
- 虛擬主機和叢集
將網域/授權對應到一組路由規則。
虛擬叢集是在虛擬主機層級指定的,Envoy 會使用它在標準叢集層級統計資料之上產生額外的統計資料。虛擬叢集可以使用正規表示式匹配。
- 路徑、前綴和標頭匹配
根據區分大小寫和不區分大小寫的前綴和確切請求路徑來路由,或使用正規表示式路徑匹配以及更複雜的匹配規則。
根據任意標頭匹配路由。
- 路徑、前綴和主機重寫
使用前綴重寫,或使用正規表示式和擷取群組的路徑重寫。
- 請求重新導向
-
在虛擬主機層級的TLS 重新導向。
- 請求逾時、重試和對沖
請求重試可以透過 HTTP 標頭或透過路由設定來指定。
Envoy 還提供請求對沖,以回應請求(每次嘗試)逾時的重試。
- 流量轉移和分割
透過執行階段值將流量從一個上游叢集轉移到另一個上游叢集,或根據權重/百分比路由將流量分散到多個上游叢集(請參閱流量轉移/分割)。
- 基於原則的路由
- 直接回應
在路由層級的非代理 HTTP 回應。
- 絕對 URL
非 TLS 轉發代理支援絕對 URL。
路由範圍
範圍路由使 Envoy 能夠對網域和路由規則的搜尋空間設定限制。
對於每個請求,HTTP 連線管理員會動態計算範圍索引鍵,以選擇路由表。
可以透過OnDemand過濾器設定與範圍相關聯的RouteConfiguration。
範圍 RDS (SRDS) API包含一組範圍資源,每個資源定義獨立的路由設定,以及一個ScopeKeyBuilder,定義 Envoy 用於查閱與每個請求對應的範圍的索引鍵建構演算法。
在以下(靜態設定的)範圍路由範例中,Envoy 會將Addr
標頭值依;
分割,透過依=
分割來確定索引鍵值配對,並使用針對索引鍵x-foo-key
找到的第一個值作為範圍索引鍵。
具體來說,如果Addr
標頭值為foo=1;x-foo-key=bar;x-bar-key=something-else
,則會將bar
計算為要查閱的對應路由設定的範圍索引鍵。
11 typed_config:
12 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
13 stat_prefix: ingress_http
14 codec_type: AUTO
15 http_filters:
16 - name: envoy.filters.http.router
17 typed_config:
18 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19 scoped_routes:
20 name: scope_by_addr
21 scope_key_builder:
22 fragments:
23 - header_value_extractor:
24 name: Addr
25 element_separator: ";"
26 element:
27 key: x-foo-key
28 separator: "="
29 scoped_route_configurations_list:
30 scoped_route_configurations:
31 - on_demand: true
32 name: scoped_route_0
33 key:
34 fragments:
35 - string_key: bar
36 route_configuration:
37 name: local_route
38 virtual_hosts:
39 - name: local_service
40 domains: ["*"]
41 routes:
42 - match:
43 prefix: "/"
44 route:
45 cluster: cluster_0
為了使索引鍵與ScopedRouteConfiguration匹配,計算的索引鍵中的片段數必須與ScopedRouteConfiguration的片段數匹配。然後依序匹配片段。
注意
在建構的索引鍵中缺少片段(視為NULL
)會導致請求無法與任何範圍匹配,也就是說,找不到請求的任何路由項目。
路由表
HTTP 連線管理員的設定擁有所有已設定的 HTTP 過濾器使用的路由表。
雖然路由過濾器是路由表的主要使用者,但其他過濾器也可以存取,以防它們想要根據請求的最終目的地做出決策。例如,內建的速率限制過濾器會查詢路由表,以根據路由確定是否應呼叫全域速率限制服務。
連線管理員會確保對特定請求取得路由的所有呼叫都是穩定的,即使決策涉及隨機性(例如,在執行階段設定路由規則的情況下)。
重試語義
Envoy 允許在路由設定中設定重試,以及針對透過請求標頭的特定請求設定重試。
以下為可行的組態設定:
- 最大重試次數
Envoy 將持續重試任意次數。
重試間隔時間取決於指數退避演算法(預設),或根據上游伺服器透過標頭回傳的資訊(如果有的話)。
注意
所有重試都包含在整體請求逾時時間內。
這樣可以避免因為大量重試而導致請求時間過長。
- 重試條件
Envoy 可以根據應用程式需求,在不同的條件類型下進行重試。例如,網路故障、所有 5xx 回應碼、等冪 4xx 回應碼等。
- 重試預算
Envoy 可以透過重試預算來限制作用中請求的重試比例,以防止它們對流量的大幅增加做出貢獻。
- 主機選擇重試外掛程式
Envoy 可以設定在重試時選取主機時套用額外的邏輯。
指定重試主機謂詞允許在選取特定主機時重新嘗試主機選取(例如,當選取已嘗試過的主機時),同時可以設定重試優先權來調整在為重試選取優先權時所使用的優先權負載。
注意
當存在 x-envoy-overloaded 時,Envoy 會重試請求。建議設定重試預算(建議)或將最大作用中重試斷路器設定為適當的值,以避免重試風暴。
請求對沖
Envoy 支援請求對沖,可以透過指定對沖策略來啟用。
這表示 Envoy 將競速多個同時的上游請求,並將第一個具有可接受標頭的回應傳回給下游。
重試策略用於判斷是否應傳回回應,或是否應等待更多回應。
目前,對沖只能在回應請求逾時時執行。這表示將在不取消初始逾時請求的情況下發出重試請求,並等待延遲回應。將會根據重試策略將第一個「良好」回應傳回下游。
此實作確保不會重複重試同一個上游請求,否則如果請求逾時然後導致 5xx 回應,可能會產生兩個可重試事件。
優先權路由
Envoy 支援在路由層級的優先權路由。
目前的優先權實作針對每個優先權層級使用不同的連線集區和斷路設定,這表示即使是 HTTP/2 請求,也會使用兩個實體連線到上游主機。
目前支援的優先權為 default
和 high
。
直接回應
Envoy 支援傳送「直接」回應。這些是預先設定的 HTTP 回應,不需要代理到上游伺服器。
有兩種方法可以在路由中指定直接回應:
設定 direct_response 欄位。這適用於所有 HTTP 回應狀態。
設定 redirect 欄位。這僅適用於重新導向回應狀態,但簡化了
Location
標頭的設定。
直接回應具有 HTTP 狀態碼和選擇性的內文。
路由組態可以內嵌指定回應內文,或指定包含內文的檔案路徑。
如果路由組態指定檔案名稱,Envoy 將在載入組態時讀取該檔案並快取其內容。
注意
如果指定了回應內文,則預設情況下其大小限制為 4KB,無論是內嵌提供還是檔案提供。
Envoy 目前將整個內文都保留在記憶體中,因此 4KB 的預設值旨在避免代理的記憶體佔用量過大。
如果需要,可以透過設定 max_direct_response_body_size_bytes 欄位來變更此限制。
如果已為路由或封閉的虛擬主機設定 response_headers_to_add
,Envoy 將在直接 HTTP 回應中包含指定的標頭。
透過一般比對進行路由
Envoy 支援使用一般比對樹狀結構來指定路由表。
這是一種比原始比對引擎更具表達力的比對引擎,允許對任意標頭進行次線性比對(不像原始比對引擎在某些情況下只能對 :authority
執行此操作)。
若要使用一般比對樹狀結構,請在虛擬主機上指定一個比對器,並將路由或路由清單做為動作。
11 typed_config:
12 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
13 stat_prefix: ingress_http
14 codec_type: AUTO
15 http_filters:
16 - name: envoy.filters.http.router
17 typed_config:
18 "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
19 route_config:
20 name: local_route
21 virtual_hosts:
22 - name: local_service
23 domains: ["*"]
24 matcher:
25 matcher_tree:
26 input:
27 name: request-headers
28 typed_config:
29 "@type": type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
30 header_name: :path
31 exact_match_map:
32 map:
33 "/new_endpoint/foo":
34 action:
35 name: route_foo
36 typed_config:
37 "@type": type.googleapis.com/envoy.config.route.v3.Route
38 match:
39 prefix: /foo
40 route:
41 cluster: cluster_0
42 request_headers_to_add:
43 - header:
44 key: x-route-header
45 value: new-value
46 "/new_endpoint/bar":
47 action:
48 name: route_bar
49 typed_config:
50 "@type": type.googleapis.com/envoy.config.route.v3.Route
51 match:
52 prefix: /bar
53 route:
54 cluster: cluster_1
55 request_headers_to_add:
56 - header:
57 key: x-route-header
58 value: new-value
59
60 "/new_endpoint/baz":
61 action:
62 name: route_list
63 typed_config:
64 "@type": type.googleapis.com/envoy.config.route.v3.RouteList
65 routes:
66 - match:
67 prefix: /baz
68 headers:
69 - name: x-match-header
70 string_match:
71 exact: foo
72 route:
73 cluster: cluster_2
74 - match:
75 prefix: /baz
76 headers:
77 - name: x-match-header
78 string_match:
79 exact: bar
80 route:
81 cluster: cluster_3
82
83 clusters:
這樣可以使用一般比對框架提供的額外比對彈性,解析用於以 routes
為基礎的路由的相同 Route
Proto 訊息。
注意
產生的路由也會指定比對條件。
除了解析路由之外,還必須滿足此條件才能達成路由比對。
當使用路徑重寫時,比對的路徑將僅取決於已解析的路由的比對條件。
在比對樹狀結構走訪期間完成的路徑比對不會影響路徑重寫。
唯一支援的輸入是請求標頭(透過HttpRequestHeaderMatchInput)。
提示
如需有關整個 API 的詳細資訊,請參閱比對 API的文件。