反向代理
將要求代理到一個或多個後端,並可設定傳輸、負載平衡、健康檢查、要求處理和緩衝選項。
語法
reverse_proxy [<matcher>] [<upstreams...>] {
# backends
to <upstreams...>
dynamic <module> ...
# load balancing
lb_policy <name> [<options...>]
lb_retries <retries>
lb_try_duration <duration>
lb_try_interval <interval>
lb_retry_match <request-matcher>
# active health checking
health_uri <uri>
health_port <port>
health_interval <interval>
health_timeout <duration>
health_status <status>
health_body <regexp>
health_headers {
<field> [<values...>]
}
# passive health checking
fail_duration <duration>
max_fails <num>
unhealthy_status <status>
unhealthy_latency <duration>
unhealthy_request_count <num>
# streaming
flush_interval <duration>
request_buffers <size>
response_buffers <size>
stream_timeout <duration>
stream_close_delay <duration>
# request/header manipulation
trusted_proxies [private_ranges] <ranges...>
header_up [+|-]<field> [<value|regexp> [<replacement>]]
header_down [+|-]<field> [<value|regexp> [<replacement>]]
method <method>
rewrite <to>
# round trip
transport <name> {
...
}
# optionally intercept responses from upstream
@name {
status <code...>
header <field> [<value>]
}
replace_status [<matcher>] <status_code>
handle_response [<matcher>] {
<directives...>
# special directives only available in handle_response
copy_response [<matcher>] [<status>] {
status <status>
}
copy_response_headers [<matcher>] {
include <fields...>
exclude <fields...>
}
}
}
上游
- <upstreams...> 是要代理的上游 (後端) 清單。
- to 是指定上游清單的另一種方式,每行一個 (或多個)。
- dynamic 設定一個動態上游模組。這允許在每次要求中動態取得上游清單。請參閱下方的 動態上游 以取得標準動態上游模組的說明。動態上游會在每次代理迴圈迭代中擷取 (也就是說,如果啟用負載平衡重試,每個要求可能會多次擷取),並且會優先於靜態上游。如果發生錯誤,代理會改用任何靜態設定的上游。
上游位址
靜態上游位址可以採用只包含通訊協定和主機/埠的 URL,或傳統的 Caddy 網路位址 形式。有效的範例
localhost:4000
127.0.0.1:4000
https://127.0.0.1:4000
https://example.com
h2c://127.0.0.1
example.com
unix//var/php.sock
unix+h2c//var/grpc.sock
localhost:8001-8006
預設情況下,會透過純文字 HTTP 連線至上游。使用 URL 格式時,可以透過簡寫的方式使用某個 scheme 來設定一些 transport
預設值。
-
使用
https://
作為 scheme 時,將會使用http
傳輸,並啟用tls
。此外,您可能需要覆寫
Host
標頭,使其與 TLS SNI 值相符,伺服器會使用此值來進行路由和憑證選擇。有關更多詳細資訊,請參閱下方的 HTTPS 區段。 -
使用
h2c://
作為 scheme 時,將會使用http
傳輸,並將 HTTP 版本 設定為允許純文字 HTTP/2 連線。 -
使用
http://
作為 scheme 與省略 scheme 相同,因為 HTTP 本來就是預設值。此語法包含在內,是為了與其他 scheme 快捷方式保持對稱。
scheme 不能混用,因為它們會修改共用傳輸設定(啟用 TLS 的傳輸無法同時傳送 HTTPS 和純文字 HTTP)。任何明確的傳輸設定都不會被覆寫,而省略 scheme 或使用其他埠不會假設特定傳輸。
使用 網路位址 格式時,網路類型會指定為上游位址的前置詞。這無法與 URL scheme 結合使用。特殊情況下,unix+h2c/
可以作為 unix/
網路與 h2c://
scheme 相同效果的捷徑。埠範圍可以作為捷徑使用,它會擴充為具有相同主機的多個上游。
上游位址不能包含路徑或查詢字串,因為這表示在代理時同時改寫要求,而此行為未定義或未受支援。如果您需要此功能,可以使用 rewrite
指令。
如果位址不是 URL(即沒有 scheme),則可以使用 佔位符,但這會讓上游成為動態靜態,表示許多不同的後端可能會在健康檢查和負載平衡方面作為單一靜態上游。如果可能,我們建議使用 動態上游 模組。使用佔位符時,必須包含埠(透過佔位符替換,或作為位址的靜態字尾)。
動態上游
Caddy 的反向代理標準配備一些動態上游模組。請注意,使用動態上游會影響負載平衡和健康檢查,具體取決於特定政策設定:動態上游不會執行主動健康檢查;如果上游清單相對穩定且一致(特別是輪詢),則負載平衡和被動健康檢查的效果最佳。理想情況下,動態上游模組只會傳回正常且可用的後端。
SRV
從 SRV DNS 記錄中擷取上游。
dynamic srv [<full_name>] {
service <service>
proto <proto>
name <name>
refresh <interval>
resolvers <ip...>
dial_timeout <duration>
dial_fallback_delay <duration>
}
- <full_name> 是要查詢記錄的完整網域名稱(即
_service._proto.name
)。 - service 是完整名稱的服務元件。
- proto 是完整名稱的協定元件。為
tcp
或udp
。 - name 是名稱元件。或者,如果
service
和proto
為空,則為要查詢的完整網域名稱。 - refresh 是重新整理快取結果的頻率。預設值:
1m
- resolvers 是用來覆寫系統解析器的 DNS 解析器清單。
- dial_timeout 是撥接查詢的逾時時間。
- dial_fallback_delay 是在產生 RFC 6555 快速備援連線之前要等待的時間。預設值:
300ms
A/AAAA
從 A/AAAA DNS 記錄中擷取上游。
dynamic a [<name> <port>] {
name <name>
port <port>
refresh <interval>
resolvers <ip...>
dial_timeout <duration>
dial_fallback_delay <duration>
versions ipv4|ipv6
}
- name 是要查詢的網域名稱。
- port 是要對後端使用的埠。
- refresh 是重新整理快取結果的頻率。預設值:
1m
- resolvers 是用來覆寫系統解析器的 DNS 解析器清單。
- dial_timeout 是撥接查詢的逾時時間。
- dial_fallback_delay 是在產生 RFC 6555 快速備援連線之前要等待的時間。預設值:
300ms
- versions 是要解析的 IP 版本清單。預設值:
ipv4 ipv6
,分別對應 A 和 AAAA 記錄。
多重
附加多個動態上游模組的結果。如果您想要備援的上游來源,這會很有用,例如:由 SRV 的次要叢集備份的 SRV 的主要叢集。
dynamic multi {
<source> [...]
}
- <source> 是動態上游的模組名稱,後面接著其組態。可以指定多個。
負載平衡
負載平衡通常用於在多個上游之間分割流量。透過啟用重試,也可以將其與一個或多個上游一起使用,以保留要求,直到可以選取正常的上游(例如,在重新開機或重新部署上游時等待並減輕錯誤)。
這在預設情況下已啟用,並使用 random
政策。預設情況下已停用重試。
-
lb_policy 是負載平衡政策的名稱,以及任何選項。預設值:
random
。對於涉及雜湊的政策,最高隨機權重 (HRW) 演算法用於確保具有相同雜湊金鑰的用戶端或要求會對應到相同的上游,即使上游清單已變更。
某些政策支援備援作為選項,如果註明,則它們會採用一個包含
fallback <policy>
的區塊,其中採用另一個負載平衡政策。對於那些政策,預設備援為random
。組態備援允許在主要政策未選取一個時使用次要政策,從而實現強大的組合。如果需要,可以多次嵌套備援。例如,
header
可用作主要政策,允許開發人員選取特定上游,並採用first
作為所有其他連線的備援,以實作主要/次要故障轉移。lb_policy header X-Upstream { fallback first }
-
random
隨機選取一個上游 -
random_choose <n>
隨機選取兩個或多個上游,然後選取負載最小的上游(n
通常為 2) -
first
選擇第一個可用的上游,依據它們在設定中定義的順序,允許主/次故障轉移;請記得同時啟用健康檢查,否則故障轉移不會發生 -
round_robin
輪流迭代每個上游 -
weighted_round_robin <weights...>
輪流迭代每個上游,尊重提供的權重。權重參數的數量應與設定的上游數量相符。權重應為非零正整數。例如,對於兩個上游和權重5 1
,第一個上游將連續被選取 5 次,然後才選取第二個上游一次,然後循環重複。 -
least_conn
選擇當前請求數最少的上游;如果多個主機的請求數最少,則會隨機選擇其中一個主機 -
ip_hash
將遠端 IP(直接對等方)對應到一個固定的上游 -
client_ip_hash
將客戶端 IP 對應到一個固定的上游;這最適合與servers > trusted_proxies
全域選項 搭配使用,該選項啟用真實客戶端 IP 解析,否則其行為與ip_hash
相同 -
uri_hash
將請求 URI(路徑和查詢)對應到一個固定的上游 -
query [key]
透過對查詢值進行雜湊,將請求查詢對應到一個固定的上游;如果未指定金鑰,則會使用後備政策來選擇上游(預設為random
) -
header [field]
透過對標頭值進行雜湊,將請求標頭對應到一個固定的上游;如果未指定標頭欄位,則會使用後備政策來選擇上游(預設為random
) -
cookie [<name> [<secret>]]
在來自客戶端的第一個請求中(當沒有 cookie 時),將使用後備政策來選擇上游(預設為random
),並將Set-Cookie
標頭新增到回應中(未指定時,預設 cookie 名稱為lb
)。cookie 值是所選上游的撥號地址,使用 HMAC-SHA256 進行雜湊(使用<secret>
作為共用密碼,未指定時為空字串)。在後續請求中,如果 cookie 存在,則會將 cookie 值對應到同一個上游(如果可用);如果不可用或找不到,則會使用後備政策選取新的上游,並將 cookie 新增到回應中。
如果您希望將特定上游用於除錯目的,您可以使用密碼雜湊上游地址,並在您的 HTTP 伺服器(瀏覽器或其他)中設定 cookie。例如,使用 PHP,您可以執行以下程式碼來計算 cookie 值,其中
10.1.0.10:8080
是您的其中一個上游地址,而secret
是您設定的密碼。echo hash_hmac('sha256', '10.1.0.10:8080', 'secret'); // cdd96966817dd14a99f47ee17451464f29998da170814a16b483e4c1ff4c48cf
您可以透過 Javascript 主控台在您的瀏覽器中設定 cookie,例如設定名稱為
lb
的 cookiedocument.cookie = "lb=cdd96966817dd14a99f47ee17451464f29998da170814a16b483e4c1ff4c48cf";
-
-
lb_retries 是如果下一個可用的主機已停用,則針對每個要求重試選擇可用後端的時間。預設情況下,重試已停用(零)。
如果
lb_try_duration
也已設定,則如果已達持續時間,則重試可能會提前停止。換句話說,重試持續時間優先於重試次數。 -
lb_try_duration 是一個 持續時間值,它定義如果下一個可用的主機已停用,則針對每個要求重試選擇可用後端的時間。預設情況下,重試已停用(零持續時間)。
客戶端將等待長達此時間,而負載平衡器會嘗試尋找可用的上游主機。一個合理的起點可能是
5s
,因為 HTTP 傳輸的預設撥號逾時時間為3s
,因此如果無法連接到第一個選定的上游,則至少允許重試一次;但請隨時進行實驗,以找到適合您用例的正確平衡。 -
lb_try_interval 是一個 持續時間值,它定義從池中選擇下一個主機之間的等待時間。預設為
250ms
。僅在上游主機的請求失敗時才相關。請注意,如果將此設定為0
並且lb_try_duration
非零,則如果所有後端都已停用且延遲時間非常短,則可能會導致 CPU 旋轉。 -
lb_retry_match 限制允許重試的請求。如果連線到上游成功,但後續往返失敗,則請求必須符合此條件才能重試。如果連線到上游失敗,則始終允許重試。預設情況下,僅重試
GET
請求。此選項的語法與 命名請求比對器 相同,但沒有
@name
。如果您只需要一個比對器,您可以在同一行上設定它。對於多個比對器,需要一個區塊。
主動健康檢查
主動健康檢查會在背景中定時執行健康檢查。若要啟用此功能,需要 health_uri
或 health_port
。
-
health_uri 是主動健康檢查的 URI 路徑(和選用查詢)。
-
health_port 是如果與上游的埠不同,則用於主動健康檢查的埠。
-
health_interval 是 持續時間值,用於定義執行主動健康檢查的頻率。預設值:
30s
。 -
health_timeout 是 持續時間值,用於定義在將後端標記為停機前,等待回覆的時間長度。預設值:
5s
。 -
health_status 是預期從正常後端收到的 HTTP 狀態碼。可以是 3 位數的狀態碼,或以
xx
結尾的狀態碼類別。例如:200
(預設值)或2xx
。 -
health_body 是子字串或正規表示式,用於比對主動健康檢查的回應主體。如果後端未傳回符合的主體,將會標記為停機。
-
health_headers 允許指定要設定在主動健康檢查要求中的標頭。如果您需要變更
Host
標頭,或需要在健康檢查中提供一些驗證給後端,這項功能會很有用。
被動健康檢查
被動健康檢查會與實際代理要求同時進行。若要啟用此功能,需要 fail_duration
。
-
fail_duration 是 持續時間值,用於定義記住失敗要求的時間長度。持續時間
0
啟用被動健康檢查;預設值為0
(關閉)。合理的起點可能是30s
,用於平衡錯誤率和回應性,讓不正常的上游重新上線;但您可以盡情嘗試,找出最適合您使用案例的平衡點。 -
max_fails 是在
fail_duration
內,將後端視為停機前所需的失敗要求最大數量;必須1
;預設值為1
。 -
unhealthy_status 如果回應傳回其中一個狀態碼,則將要求計為失敗。可以是 3 位數的狀態碼或以
xx
結尾的狀態碼類別,例如:404
或5xx
。 -
unhealthy_latency 是 持續時間值,如果取得回應需要這麼長的時間,則將要求計為失敗。
-
unhealthy_request_count 是將後端標記為停機前,允許同時發送給後端的請求數量。換句話說,如果特定後端目前正在處理這麼多請求,則會被視為「過載」,而其他後端將優先處理。
這應該是一個相當大的數字;設定這項功能表示代理程式將限制為
unhealthy_request_count × upstreams_count
的總同時請求數量,而超過此點的任何請求都將導致錯誤,因為沒有可用上游。
事件
當上游從正常轉為不正常或反之亦然時,事件會被發出。這些事件可用於觸發其他動作,例如傳送通知或記錄訊息。事件如下:
- 當上游在先前不正常時被標記為正常時,會發出
healthy
- 當上游從原本健康狀態標記為不健康時,會發出
unhealthy
在兩種情況下,host
都會包含在事件的元資料中,以識別已變更狀態的上游。例如,它可以用作 {event.data.host}
的佔位符,搭配 exec
事件處理常式。
串流
預設情況下,代理會部分緩衝回應以提升網路效率。
代理也支援 WebSocket 連線,執行 HTTP 升級要求,然後將連線轉換為雙向通道。
-
flush_interval 是 持續時間值,用於調整 Caddy 應多久將回應緩衝區快取到客戶端。預設情況下,不會執行定期快取。負值(通常為 -1)表示「低延遲模式」,它會完全停用回應緩衝,並在每次寫入客戶端後立即快取,而且即使客戶端提早中斷連線,也不會取消對後端的請求。如果回應套用下列其中一項,則會忽略此選項,並立即將回應快取到客戶端:
Content-Type: text/event-stream
Content-Length
不明- 代理兩端的 HTTP/2,
Content-Length
不明,而且Accept-Encoding
未設定或為「identity」
-
request_buffers 會導致代理從請求主體讀取多達
<size>
位元組的資料量到緩衝區中,然後再將其傳送至上游。這非常低效,而且只應在上游需要立即讀取請求主體時才執行(這是上游應用程式應修正的問題)。這接受 go-humanize 支援的所有大小格式。 -
response_buffers 會導致代理程式從回應主體讀取多達
<size>
位元組的資料,並將其讀入緩衝區,然後再傳回給客戶端。基於效能考量,應盡可能避免使用此功能,但如果後端有較嚴格的記憶體限制,則此功能可能會很有用。此功能可接受 go-humanize 支援的所有大小格式。 -
stream_timeout 是一個 持續時間值,在該值之後,例如 WebSockets 等串流要求將在逾時結束時強制關閉。這基本上會取消連線,如果連線保持開啟時間過長。合理的起點可能是
24h
,以移除超過一天的舊連線。預設:無逾時。 -
stream_close_delay 是一個 持續時間值,會延遲例如 WebSockets 等串流要求在卸載設定檔時強制關閉;串流將保持開啟,直到延遲完成。換句話說,啟用此功能可防止串流在 Caddy 的設定檔重新載入時立即關閉。啟用此功能可能是個好主意,以避免大量重新連線的客戶端因前一個設定檔關閉而關閉連線。合理的起點可能是
5m
,以允許使用者在設定檔重新載入後自然離開頁面 5 分鐘。預設:無延遲。
標頭
代理程式可以在自己和後端之間處理標頭
-
header_up 設定、新增(使用
+
前綴)、刪除(使用-
前綴),或在傳送至後端的請求標頭中執行替換(使用兩個參數,一個搜尋和一個替換)。 -
header_down 設定、新增(使用
+
前綴)、刪除(使用-
前綴),或在從後端傳送至下游的回應標頭中執行替換(使用兩個參數,一個搜尋和一個替換)。
例如,設定請求標頭,覆寫任何現有值
header_up Some-Header "the value"
新增回應標頭;請注意,標頭欄位可以有多個值
header_down +Some-Header "first value"
header_down +Some-Header "second value"
刪除請求標頭,防止其傳送至後端
header_up -Some-Header
刪除所有符合的請求標頭,使用字尾比對
header_up -Some-*
刪除所有請求標頭,以便個別新增您想要的標頭(不建議使用)
header_up -*
對請求標頭執行正規表示式替換
header_up Some-Header "^prefix-([A-Za-z0-9]*)$" "replaced-$1-suffix"
使用的正規表示式語言是 RE2,包含在 Go 中。請參閱 RE2 語法參考 和 Go regexp 語法概觀。替換字串會擴充,允許使用擷取的值,例如 $1
是第一個擷取群組。
預設值
預設情況下,Caddy 會將傳入的標頭(包括 Host
)傳遞到後端,不會進行修改,但有三個例外
- 它會設定或擴充
X-Forwarded-For
標頭欄位。 - 它會設定
X-Forwarded-Proto
標頭欄位。 - 它會設定
X-Forwarded-Host
標頭欄位。
對於這些 X-Forwarded-*
標頭,預設情況下,代理伺服器會忽略傳入請求中的值,以防止欺騙。
如果 Caddy 不是您的客戶端連線的第一個伺服器(例如,當 CDN 在 Caddy 之前時),您可以使用 IP 範圍 (CIDR) 的清單來設定 trusted_proxies
,這些範圍是傳入請求受信任的,可以傳送這些標頭的良好值。
強烈建議您透過 servers > trusted_proxies
全域選項 設定這個,而不是在代理伺服器中設定,這樣才能套用於您的伺服器中的所有代理處理常式,而且這具有啟用用戶端 IP 解析的優點。
此外,在使用 http
傳輸 時,如果在用戶端的請求中遺漏了 Accept-Encoding: gzip
標頭,則會設定該標頭。這允許上游在可以的情況下提供壓縮內容。可以在傳輸上使用 compression off
來停用此行為。
HTTPS
由於(大多數)標頭在被代理時會保留其原始值,因此在代理到 HTTPS 時,通常需要使用設定的上游地址覆寫 Host
標頭,以便 Host
標頭與 TLS ServerName 值相符
reverse_proxy https://example.com {
header_up Host {upstream_hostport}
}
X-Forwarded-Host
標頭仍然會 預設 傳遞,因此如果上游需要知道原始 Host
標頭值,它仍然可以使用該標頭。
改寫
預設情況下,Caddy 會使用與傳入請求相同的 HTTP 方法和 URI 執行上游請求,除非在它到達 reverse_proxy
之前在中間軟體鏈中執行重寫。
在代理之前,會複製請求;這可確保在處理常式期間對請求所做的任何修改不會洩漏到其他處理常式。這在代理之後需要繼續處理的情況下很有用。
除了 標頭操作 之外,請求的方法和 URI 可以在傳送到上游之前進行變更
- method 變更複製請求的 HTTP 方法。如果方法變更為
GET
或HEAD
,則此處理常式不會將傳入請求的本文傳送到上游。如果您希望允許不同的處理常式使用請求本文,這會很有用。 - rewrite 變更複製請求的 URI(路徑和查詢)。這類似於
rewrite
指令,但它不會將重寫保留在此處理常式的範圍之外。
這些改寫通常適用於「預先檢查要求」等模式,其中會將要求傳送至另一部伺服器,以協助決定如何繼續處理目前的請求。
例如,可以將要求傳送至驗證閘道,以決定要求是否來自經過驗證的使用者(例如要求具有階段性 Cookie),且應繼續處理,或應改導向至登入頁面。針對此模式,Caddy 提供捷徑指令 forward_auth
,以略過大部分設定樣板。
傳輸
Caddy 的代理 傳輸 是可插入的
- 傳輸 定義如何與後端通訊。預設為
http
。
http
傳輸
transport http {
read_buffer <size>
write_buffer <size>
max_response_header <size>
proxy_protocol v1|v2
dial_timeout <duration>
dial_fallback_delay <duration>
response_header_timeout <duration>
expect_continue_timeout <duration>
resolvers <ip...>
tls
tls_client_auth <automate_name> | <cert_file> <key_file>
tls_insecure_skip_verify
tls_timeout <duration>
tls_trusted_ca_certs <pem_files...>
tls_server_name <server_name>
tls_renegotiation <level>
tls_except_ports <ports...>
keepalive [off|<duration>]
keepalive_interval <interval>
keepalive_idle_conns <max_count>
keepalive_idle_conns_per_host <count>
versions <versions...>
compression off
max_conns_per_host <count>
}
-
讀取緩衝區 是讀取緩衝區的大小(以位元組為單位)。它接受 go-humanize 支援的所有格式。預設:
4KiB
。 -
寫入緩衝區 是寫入緩衝區的大小(以位元組為單位)。它接受 go-humanize 支援的所有格式。預設:
4KiB
。 -
最大回應標頭 是要從回應標頭讀取的最大位元組數。它接受 go-humanize 支援的所有格式。預設:
10MiB
。 -
代理通訊協定 在與上游的連線中啟用 PROXY 通訊協定(由 HAProxy 推廣),並在前面加上真實客戶端 IP 資料。如果 Caddy 位於另一個代理之後,這最適合與
servers > trusted_proxies
全域選項 搭配使用。支援版本v1
和v2
。只有在您知道上游伺服器能夠解析 PROXY 通訊協定時,才應使用此功能。預設情況下,此功能已停用。 -
撥接逾時 是在連接到上游 Socket 時要等待的最長 持續時間。預設:
3s
。 -
撥接備援延遲 是在產生 RFC 6555 快速備援連線之前要等待的最長 持續時間。負值會停用此功能。預設:
300ms
。 -
回應標頭逾時 是在從上游讀取回應標頭時要等待的最長 持續時間。預設:無逾時。
-
預期繼續逾時 是在完全寫入要求標頭後,等待上游的第一個回應標頭時要等待的最長 持續時間(如果要求具有標頭
Expect: 100-continue
)。預設:無逾時。 -
讀取逾時 是在等待後端下一次讀取時要等待的最長 持續時間。預設:無逾時。
-
寫入逾時 是在等待後端下一次寫入時要等待的最長 持續時間。預設:無逾時。
-
解析器 是 DNS 解析器的清單,用於覆寫系統解析器。
-
tls 使用 HTTPS 與後端連線。如果您使用
https://
範例或埠:443
指定後端,或設定以下任一tls_*
選項,此功能將會自動啟用。 -
tls_client_auth 透過兩種方式之一啟用 TLS 用戶端驗證:(1) 指定 Caddy 應取得並持續更新憑證的網域名稱,或 (2) 指定憑證和金鑰檔案,以進行後端 TLS 用戶端驗證。
-
tls_insecure_skip_verify 關閉 TLS 交握驗證,使連線不安全且容易受到中間人攻擊。請勿在實際環境中使用。
-
tls_timeout 是等待 TLS 交握完成的最長 持續時間。預設值:無逾時。
-
tls_trusted_ca_certs 是 PEM 檔案清單,用於指定連線至後端時要信任的 CA 公開金鑰。
-
tls_server_name 設定在 TLS 交握中驗證收到的憑證時使用的伺服器名稱。預設值會使用上游位址的主機部分。
只有在上游位址與上游可能使用的憑證不符時,才需要覆寫此設定。例如,如果上游位址是 IP 位址,則需要將此設定設定為上游伺服器提供的 Hostname。
可以使用要求保留字元,這種情況下,每次要求都會使用 HTTP 傳輸設定的複製品,這可能會造成效能損失。
-
tls_renegotiation 設定 TLS 重新協商層級。TLS 重新協商是在第一次交握後執行後續交握的動作。層級可以是下列其中之一:
never
(預設值) 會停用重新協商。once
允許遠端伺服器在每個連線中要求重新協商一次。freely
允許遠端伺服器重複要求重新協商。
-
tls_except_ports 當啟用 TLS 時,如果上游目標使用指定的埠之一,則會針對這些連線停用 TLS。在設定動態上游時,這可能很有用,因為某些上游會預期 HTTP 要求,而其他上游會預期 HTTPS 要求。
-
keepalive 是
off
或 持續時間值,用於指定連線開啟的時間長度 (逾時)。預設值:2m
。 -
keepalive_interval 是連線狀態探查之間的 持續時間。預設值:
30s
。 -
keepalive_idle_conns 定義要保持連線的連線最大數量。預設值:無限制。
-
keepalive_idle_conns_per_host 如果非零,則控制每個主機要保留的最大閒置(保持連線)連線。預設:
32
。 -
versions 允許自訂要支援的 HTTP 版本。特殊情況下,「h2c」是一個有效值,它會啟用至上游的明文 HTTP/2 連線(不過,這是一個非標準功能,不會使用 Go 的預設 HTTP 傳輸,因此它與其他功能互斥;可能會變更或移除)。預設:
1.1 2
,或者如果架構是h2c://
,則為h2c 2
-
compression 可透過將其設定為
off
來停用對後端的壓縮。 -
max_conns_per_host 選擇性地限制每個主機的總連線數,包括撥號、活動和閒置狀態的連線。預設:無限制。
fastcgi
傳輸
transport fastcgi {
root <path>
split <at>
env <key> <value>
resolve_root_symlink
dial_timeout <duration>
read_timeout <duration>
write_timeout <duration>
capture_stderr
}
-
root 是網站的根目錄。預設:
{http.vars.root}
或目前的作業目錄。 -
split 是分割路徑以在 URI 結尾取得 PATH_INFO 的位置。
-
env 將額外的環境變數設定為指定的值。可為多個環境變數指定多次。
-
resolve_root_symlink 如果存在符號連結,則啟用將
root
目錄解析為其實際值。 -
dial_timeout 是連線至上游 socket 時要等待的時間長度。接受 持續時間值。預設:
3s
。 -
read_timeout 是從 FastCGI 伺服器讀取時要等待的時間長度。接受 持續時間值。預設:無逾時。
-
write_timeout 是傳送至 FastCGI 伺服器時要等待的時間長度。接受 持續時間值。預設:無逾時。
-
capture_stderr 啟用擷取和記錄上游 fastcgi 伺服器在
stderr
上傳送的任何訊息。記錄預設為WARN
等級。如果回應有4xx
或5xx
狀態,則會改用ERROR
等級。預設會略過stderr
。
攔截回應
反向代理程式可以設定為攔截後端回應。為了簡化此操作,可以定義回應比對器(類似於請求比對器的語法),並且會呼叫第一個比對的 handle_response
路由。
當呼叫回應處理常式時,後端的回應不會寫入至用戶端,而且會執行設定的 handle_response
路由,並且由該路由寫入回應。如果路由沒有寫入回應,則請求處理會繼續進行,使用任何在這個 reverse_proxy
之後 排序 的處理常式。
- @name 是 回應比對器 的名稱。只要每個回應比對器都有獨特的名稱,就可以定義多個比對器。可以根據狀態碼和回應標頭的存在或值比對回應。
- replace_status 當給定的比對器比對時,只會變更回應的狀態碼。
- handle_response 定義當給定的比對器比對時(或如果省略比對器,則所有回應)要執行的路由。會套用第一個比對的區塊。在
handle_response
區塊中,可以使用任何其他 指令。
此外,在 handle_response
中,可以使用兩個特殊的處理常式指令
- copy_response 將從後端接收的回應本文複製回用戶端。選擇性地允許在這樣做的同時變更回應的狀態碼。此指令 在
respond
之前排序。 - copy_response_headers 將後端的回應標頭複製到用戶端,選擇性地包含或排除標頭欄位清單(無法同時指定
include
和exclude
)。此指令 在header
之後排序。
三個佔位符會在 handle_response
路由中提供
{rp.status_code}
後端回應的狀態碼。{rp.status_text}
後端回應的狀態文字。{rp.header.*}
後端回應的標頭。
回應比對器
回應比對器 可用於根據特定條件篩選(或分類)回應。
status
status <code...>
依據 HTTP 狀態碼。
- <code...> 是 HTTP 狀態碼清單。特殊情況是字串,例如
2xx
和3xx
,分別符合200
-299
和300
-399
範圍內的所有狀態碼。
標頭
請參閱 header
要求比對器以取得支援的語法。
範例
反向代理所有要求至本機後端
example.com {
reverse_proxy localhost:9005
}
example.com {
reverse_proxy node1:80 node2:80 node3:80
}
相同,但僅限於 /api
內的要求,並使用 cookie
政策 進行黏著。
example.com {
reverse_proxy /api/* node1:80 node2:80 node3:80 {
lb_policy cookie api_sticky
}
}
使用 主動健康檢查 來判斷哪些後端是正常的,並針對失敗的連線啟用 重試,並在找到正常的後端之前暫留要求
example.com {
reverse_proxy node1:80 node2:80 node3:80 {
health_uri /healthz
lb_try_duration 5s
}
}
組態一些 傳輸選項
example.com {
reverse_proxy localhost:8080 {
transport http {
dial_timeout 2s
response_header_timeout 30s
}
}
}
反向代理至 HTTPS 上游
example.com {
reverse_proxy https://example.com {
header_up Host {upstream_hostport}
}
}
反向代理至 HTTPS 上游,但 ⚠️ 停用 TLS 驗證。由於這會停用 HTTPS 提供的所有安全性檢查,因此不建議這麼做;如果可能,建議在私人網路中透過 HTTP 進行代理,因為這可以避免虛假的安全感
example.com {
reverse_proxy 10.0.0.1:443 {
transport http {
tls_insecure_skip_verify
}
}
}
您也可以透過明確 信任上游的憑證,以及(選擇性地)設定 TLS-SNI 以符合上游憑證中的主機名稱,來與上游建立信任
example.com {
reverse_proxy 10.0.0.1:443 {
transport http {
tls_trusted_ca_certs /path/to/cert.pem
tls_server_name app.example.com
}
}
}
在代理之前移除路徑字首;但請注意 子資料夾問題
example.com {
handle_path /prefix/* {
reverse_proxy localhost:9000
}
}
在代理之前使用 rewrite
取代路徑字首
example.com {
handle_path /old-prefix/* {
rewrite * /new-prefix{path}
reverse_proxy localhost:9000
}
}
X-Accel-Redirect
支援,例如透過 攔截回應 來依要求提供靜態檔案
example.com {
reverse_proxy localhost:8080 {
@accel header X-Accel-Redirect *
handle_response @accel {
root * /path/to/private/files
rewrite * {rp.header.X-Accel-Redirect}
method * GET
file_server
}
}
}
針對來自上游的錯誤提供自訂錯誤頁面,透過 攔截錯誤回應 依據狀態碼
example.com {
reverse_proxy localhost:8080 {
@error status 500 503
handle_response @error {
root * /path/to/error/pages
rewrite * /{rp.status_code}.html
file_server
}
}
}
example.com {
reverse_proxy {
dynamic a example.com 9000
}
}
example.com {
reverse_proxy {
dynamic srv _api._tcp.example.com
}
}