本指南說明如何排解外部應用程式負載平衡器的設定問題。調查問題前,請先熟悉下列頁面:
排解網路分析器的常見問題
網路分析器會自動監控虛擬私有雲網路設定,並偵測不盡理想的設定和錯誤設定。識別網路故障、提供根本原因資訊,並建議可能的解決方法。如要瞭解網路分析器會自動偵測哪些設定錯誤,請參閱網路分析器說明文件中的「負載平衡器深入分析」。
Network Analyzer 是 Network Intelligence Center 的一部分,可在 Google Cloud 控制台中使用。
前往「Network Analyzer」後端的平衡模式不相容
建立負載平衡器時,可能會看到以下錯誤:
Validation failed for instance group INSTANCE_GROUP: backend services 1 and 2 point to the same instance group but the backends have incompatible balancing_mode. Values should be the same.
當您嘗試在兩個不同的負載平衡器中使用同一個後端,且後端沒有相容的平衡模式時,就會發生這種情況。
如要瞭解詳情,請參考下列資源:
排解一般連線問題
未說明的「5XX」錯誤
「HTTP 5XX」錯誤可能由第一層 GFE、第二層 GFE 或後端傳回,具體取決於錯誤條件發生的位置。
本節說明如何排解 5XX 錯誤,這類錯誤可能發生在以 GFE 為基礎的外部應用程式負載平衡器要求分配程序的不同階段。
使用 Cloud Logging 找出「5XX」錯誤的來源
如果錯誤狀況是由負載平衡器 Proxy 與其後端之間的通訊問題造成,負載平衡器會產生 HTTP 錯誤回應代碼 (5XX),並將該錯誤回應代碼傳回用戶端。並非所有 HTTP 5XX 錯誤都是由負載平衡器產生,例如,如果後端向負載平衡器傳送 HTTP 5XX 回應,負載平衡器會將該回應轉送至用戶端。
如要判斷 HTTP 5XX 回應是從後端轉送,還是由負載平衡器 Proxy 產生,請在 Cloud Logging 中查看 statusDetails 欄位。
- 如果
statusDetails為response_sent_by_backend,表示負載平衡器轉送了後端的 5XX 回應。請排解後端問題。 - 如果
statusDetails是任何其他失敗訊息,則 5XX 回應是由負載平衡器產生。
如果變更全域外部應用程式負載平衡器的設定 (例如新增或移除後端服務),可能會在短時間內看到 HTTP 502 回應,其中 statusDetails 為 failed_to_pick_backend。將設定變更傳播至全球 GFE 時,這是正常現象。
開始排解問題前,請先確認後端健康狀態
排解 5XX 錯誤前,請先確認後端是否健康,以及健康狀態檢查是否通過。如果後端健康狀態不良,第二層 GFE 就無法將要求轉送至後端,即使其他設定都正確,也可能導致 5XX 錯誤。
- 確認防火牆規則已設為允許健康狀態檢查。如果沒有,健康狀態檢查就會失敗,負載平衡器記錄可能會顯示
failed_to_pick_backend的statusDetails。 - 確認健康狀態檢查流量傳送至後端 VM。如要使用這項功能,請啟用健康狀態檢查記錄功能,並搜尋成功的記錄項目。如果是新的負載平衡器,您可能不會立即看到成功的健康狀態檢查記錄項目。這可能是因為後端的初始健康狀態尚未從
UNHEALTHY變更為其他狀態。只有在健康狀態檢查探測器收到後端傳送的 HTTP 200 OK 回應後,才會看到成功的健康狀態檢查記錄項目。
如果健康狀態檢查失敗,請排解後端應用程式和防火牆規則的問題。如果健康狀態檢查通過,但仍看到 5XX 錯誤,請查看 Cloud Logging 中的 statusDetails 欄位,找出錯誤來源,詳情請參閱下一節。
根據statusDetails排解錯誤
如果 HTTP 5XX 錯誤持續發生,請使用 Cloud Logging 中的 statusDetails 欄位找出原因,並據此排解問題。
全域外部應用程式負載平衡器和區域性外部應用程式負載平衡器會產生有意義的 HTTP 狀態碼,例如 HTTP 503 服務無法使用和 HTTP 504 閘道逾時。
傳統版應用程式負載平衡器一律會針對負載平衡器產生的所有錯誤,使用 HTTP 502 Bad Gateway 狀態碼。
| statusDetails | 可能原因和解決方法 |
|---|---|
failed_to_pick_backendfailed_to_pick_backend_by_hash |
原因:第二層 GFE 無法選取健康狀態良好的後端來轉送要求。 發生這項錯誤的原因如下:
解決方法:
|
failed_to_connect_to_backend |
原因:第二層 GFE 無法與後端執行個體建立連線 (無法取得 SYN-ACK)。這項錯誤也可能是由內部 GFE 錯誤所造成,導致 GFE 無法連線至後端,或因區域性服務中斷或網路中斷 (例如光纖中斷),導致第一層 GFE 無法與第二層 GFE 通訊。 解決方法:
|
backend_connection_closed_before_data_sent_to_client |
原因:第二層 GFE 與後端之間的連線意外關閉,導致回應無法傳送至用戶端。這項問題可能是由後端網路伺服器或中介裝置所造成。如果使用 GKE 時,Pod 正在縮減或終止,且負載平衡器後端屬於 NEG 類型,也可能發生這種情況。 解決方法:
|
backend_timeout |
原因:第二層 GFE 與後端建立連線,但後端未在設定的後端服務逾時內傳送回應。 解決方法:
|
retriable_error |
原因:如果基礎架構即程式碼工具 (例如 Terraform) 更新負載平衡器規則的方式,是先暫時移除網址對應規則再重新加入,就可能發生這項 503 錯誤。此外,在推出或推送設定期間,如果 Google 網路或設定發生暫時性內部問題,也可能導致這項錯誤。 解決方法:
|
解決 HTTP 408 錯誤
如果是 HTTP 流量,用戶端完成傳送要求的最長時間等於後端服務逾時時間。如果看到 HTTP 408 回應,且 jsonPayload.statusDetail 為 client_timed_out,表示以 Proxy 處理用戶端要求或後端回應時,進度不足。如果問題是由用戶端效能問題所造成,您可以增加後端服務逾時時間來解決。
經過負載平衡後的流量沒有原始用戶端的來源位址
後端看到的封包來源 IP 位址「不是」負載平衡器的外部 IP 位址,外部應用程式負載平衡器等 Proxy 負載平衡器會使用兩個 TCP 連線,將流量從用戶端傳輸至後端:
- 連線 1:從原始用戶端連至負載平衡器 (GFE 或僅限 Proxy 的子網路)
- 連線 2:從負載平衡器 (GFE 或僅限 Proxy 子網路) 到後端 VM 或端點
每個連線的來源和目的地 IP 位址,會因使用的外部應用程式負載平衡器類型而異。詳情請參閱「用戶端封包的來源 IP 位址 」。
嘗試查看 Cloud Storage bucket 中的物件時遇到權限錯誤
如要透過負載平衡提供物件,Cloud Storage 物件必須處於可公開存取的狀態。請務必針對要提供的物件更新權限,將其設為可公開讀取。
網址未提供預期的 Cloud Storage 物件
系統會依據網址對應和要求的網址決定要提供的 Cloud Storage 物件。如果要求路徑對應到網址對應中的後端 bucket,則會透過將完整要求路徑附加至網址對應指定的 Cloud Storage bucket,藉此決定 Cloud Storage 物件。
舉例來說,如果您將 /static/* 對應至 gs://[EXAMPLE_BUCKET],https://<GCLB IP or Host>/static/path/to/content.jpg 的要求會嘗試提供 gs://[EXAMPLE_BUCKET]/static/path/to/content.jpg。如果該物件不存在,您會收到下列錯誤訊息,而非物件:
NoSuchKeyThe specified key does not exist.
未執行壓縮
外部應用程式負載平衡器本身不會壓縮或解壓縮回應,但可以提供由後端服務產生,並使用 gzip 或 DEFLATE 等工具壓縮的回應。
如果負載平衡器提供的回應沒有依預期壓縮,請檢查在執行個體上執行的網路伺服器軟體是否設為需壓縮回應。根據預設,部分網路伺服器軟體會自動針對包含 Via 標頭的要求停用壓縮功能,這表示要求是經由 Proxy 轉送。由於外部應用程式負載平衡器是 Proxy,因此會依據 HTTP 規格所需,在每個要求中新增 Via 標頭。如要啟用壓縮功能,您可能需要覆寫網路伺服器的預設設定,指示伺服器即使要求含有 Via 標頭,也需壓縮回應。
如要設定 nginx 後端,透過外部應用程式負載平衡器提供壓縮回應,請按照下列步驟操作:
- 適當設定
gzip_proxied指令 (例如設為any), - 將
gzip_vary指令設為on。
如要設定 Apache 後端,透過外部應用程式負載平衡器代理提供壓縮回應,請按照下列步驟操作:
- 使用「
DEFLATE」篩選器, - 使用
mod_headers模組將Vary Accept-Encoding新增至回應標頭。
排解後端健康狀態不良的問題
排解後端 HTTP/2 問題
請確認後端執行個體健康狀態良好,且支援 HTTP/2 通訊協定。您可以透過 HTTP/2 測試與後端執行個體的連線,藉此驗證這項設定。確認 VM 使用符合 HTTP/2 規格的加密套件。舉例來說,HTTP/2 不允許某些 TLS 1.2 加密套件。請參閱 TLS 1.2 加密套件黑名單。
確認 VM 使用 HTTP/2 通訊協定後,請確認防火牆設定允許健康狀態檢查工具和負載平衡器通過。
如果防火牆設定沒有問題,請確認負載平衡器已設為與 VM 上的正確通訊埠通訊。
排解在電信級 NAT 後方運作的用戶端連線中斷問題
用戶端透過中介有狀態裝置 (例如電信業者級 NAT (CGNAT)) 連線至外部應用程式負載平衡器時,CGNAT 會在狀態表中追蹤每個有效的 TCP 連線。許多 CGNAT 會強制執行短暫的閒置逾時,比負載平衡器的用戶端 HTTP 保持運作逾時 (預設為 610 秒) 和用戶端 HTTP 連線集區中的閒置連線逾時還要短。
如果連線閒置時間超過 CGNAT 的閒置逾時時間,CGNAT 會在不傳送 TCP FIN 或 RST 封包至任一端點的情況下,自動從狀態表中移除連線項目。由於用戶端和負載平衡器仍認為連線已開啟,因此用戶端透過該連線傳送的下一個 HTTP 要求會遭到 CGNAT 捨棄或拒絕,導致要求失敗。
如要避免在 CGNAT 或其他有狀態裝置後方運作的用戶端連線中斷,請執行下列任一操作:
將 HTTP 用戶端連線集區中的閒置連線逾時時間,縮短至低於 CGNAT 閒置逾時時間和負載平衡器的用戶端 HTTP 保持運作逾時時間,讓用戶端在 NAT 狀態到期前正常關閉閒置連線。
設定應用程式層級的 Keepalive (例如定期傳送 HTTP/2
PING框架),間隔時間應短於 CGNAT 閒置逾時時間 (但閒置連線上的PING框架之間至少應間隔 30 秒,以免觸發頻率限制)。雖然在沒有任何串流處於活動狀態時,HTTP/2PING框架不會重設負載平衡器的用戶端 HTTP 保持運作逾時,但會讓中介 NAT 對應保持活動狀態,讓連線保持有效或正常關閉。縮短用戶端作業系統 TCP 保持運作間隔 (例如 Linux 上的
net.ipv4.tcp_keepalive_time),使其小於 CGNAT 閒置逾時時間,這樣定期的傳出 TCP 探測就能防止 NAT 對應逾時。請注意,TCP 保持運作探測會在傳輸層處理,不會重設負載平衡器的用戶端 HTTP 保持運作逾時。
疑難排解 gRPC 問題
如果您使用雙向 gRPC 串流,且用戶端連線至全域外部應用程式負載平衡器,則當用戶端執行立即半關閉 (在建立串流後立即傳送 END_STREAM 旗標,而不傳送任何資料) 時,後端伺服器可能會停止運作。這是因為 HTTP/2 最佳化與 gRPC 框架規格之間發生衝突。
全域外部應用程式負載平衡器會將用戶端的 HEADERS 框架和空白 DATA 框架 (含 END_STREAM) 合併為單一 HEADERS 框架 (含 END_STREAM),然後轉送至後端,藉此最佳化 HTTP/2 流量。這是 RFC 7540 規定的標準 HTTP/2 最佳化。當影格幾乎同時到達 (延遲 0 毫秒) 時,負載平衡器會執行這項合併作業。
部分 gRPC 伺服器實作 (例如 grpc-go) 不支援在 HEADERS 框架上接收 END_STREAM 旗標,導致後端無限期等待。gRPC over HTTP/2 規格嚴格要求,必須在最後收到的 DATA 框架上,以 END_STREAM 旗標表示串流結尾 (EOS)。
為避免後端伺服器停止回應,以及連線保持開啟,直到用戶端傳送 RST_STREAM 強制終止連線,您可以採用下列其中一種解決方法:
在半關閉串流之前,在用戶端引入短暫延遲 (例如 10 毫秒以上)。這樣一來,負載平衡器就不會合併影格,因為
HEADERS影格已經轉送。請確保用戶端在半關閉串流前,至少傳送一則資料訊息。
如果可以,請改用區域性外部應用程式負載平衡器,這種負載平衡器不會合併
HEADERS框架和空白DATA框架,而是會分別轉送。
排解外部後端和網際網路 NEG 問題
調查問題前,請先詳閱下列頁面:
流量無法連上端點
設定服務後,只要符合下列條件,即可透過外部應用程式負載平衡器連上新端點:
- 端點已連結至網際網路 NEG。
- 相關聯的 FQDN 可成功解析 DNS (如果您使用的是 FQDN 端點類型)。
- 可透過網際網路存取端點。
如果流量無法到達端點,導致 502 錯誤代碼,請使用 dig 或 nslookup 等工具查詢 _cloud-eoips.googleusercontent.com DNS TXT 記錄。請記下 CIDR (ip4: 後方),並確認防火牆或雲端存取控管清單 (ACL) 允許這些範圍。
設定外部後端後,傳送至外部後端的要求失敗,並顯示 5xx 錯誤
- 勾選「Logging」。
- 確認網路端點群組已為外部後端設定正確的 IP:通訊埠或 FQDN:通訊埠。
- 如果使用 FQDN,請確認可透過 Google 公用 DNS 解析。您可以按照這些步驟,或直接透過網頁介面,確認 FQDN 可透過 Google 公用 DNS 解析。
- 如果您只透過外部 IP 存取負載平衡器,且來源網路伺服器預期會收到主機名稱,請務必設定自訂要求標頭,將有效的 HTTP 主機標頭傳送至後端。
- 如果您透過 HTTPS 或 HTTP2 (在後端服務的
protocol欄位中設定) 與設為INTERNET_FQDN_PORT外部後端端點的後端通訊,請確認來源提供有效的 TLS (SSL) 憑證,且設定的 FQDN 與憑證 SAN 清單中的 SAN (主體別名) 相符。有效憑證是指由公開憑證授權單位簽署且未過期的憑證。 - 使用
INTERNET_FQDN_PORT外部後端端點時,負載平衡器不接受自行簽署的憑證,並會拒絕這類憑證。 - 搭配
INTERNET_IP_PORT類型端點使用 HTTPS 或 HTTP/2 時,系統不會執行 SSL 憑證驗證/SAN 檢查。這表示您可以使用自行簽署的憑證。使用 SSL 時,建議使用INTERNET_FQDN_PORT端點,確保伺服器憑證和 SAN 可通過驗證。
Cloud CDN 未快取外部後端的回應
請確認下列事項:
- 您已在後端服務啟用 Cloud CDN,其中包含指向外部後端的 NEG,方法是將 enableCDN 設為 true。
- 外部後端提供的回應符合 Cloud CDN 快取規定。舉例來說,您從來源傳送
Cache-Control: public, max-age=3600回應標頭。
排解無伺服器 NEG 問題
調查問題前,請先詳閱下列頁面:
要求失敗,並傳回 404 錯誤
確認基礎無伺服器資源 (例如 App Engine、Cloud Run functions 或 Cloud Run 服務) 仍在執行中。如果無伺服器資源已刪除,但無伺服器 NEG 仍存在,外部應用程式負載平衡器會繼續嘗試將要求轉送至不存在的服務。這會導致 404 回應。
一般來說,外部應用程式負載平衡器無法偵測底層無伺服器資源是否正常運作。也就是說,如果某個區域的服務傳回錯誤,但該區域的整體 Cloud Run、Cloud Run functions 或 App Engine 基礎架構正常運作,外部應用程式負載平衡器就不會自動將流量導向其他區域。請務必先徹底測試新版服務,再將使用者流量轉送至該服務。
處理網址遮罩不符的情況
如果將設定的網址遮罩套用至使用者要求網址,但未產生服務名稱,或產生的服務名稱不存在,負載平衡器可能會根據使用的無伺服器運算平台,以不同方式處理這些不相符的情況。
Cloud Run:如果網址遮罩不相符,負載平衡器會傳回 HTTP 錯誤 404 (找不到)。
Cloud Run functions:如果網址遮罩不相符,負載平衡器會傳回 HTTP 錯誤 404 (找不到)。
API Gateway:如果網址遮罩不相符,負載平衡器會傳回 HTTP 錯誤 404 (找不到)。
App Engine:如果網址遮罩不相符,App Engine 會使用 dispatch.yaml 和 App Engine 的預設轉送邏輯,判斷要將要求傳送至哪項服務。
排解 Google 代碼閘道插入問題
Google 代碼閘道未正確插入代碼,或導致錯誤。
如要解決這個問題,請使用 Google Cloud 控制台Logs Explorer,分析負載平衡器產生的記錄。Google 代碼閘道問題不會影響網頁要求的整體 HTTP 回應代碼或 statusDetails。即使 Google 代碼插入失敗,系統仍會傳送 HTTP 回應,不會進行任何修改。如要找出閘道錯誤,請在負載平衡器的 JSON 酬載中,檢查外掛程式執行的 grpcStatus。
請確認已在後端服務啟用 Cloud Logging,這些服務會為 Google 代碼閘道有效的網域提供網站內容。如要設定這項功能,請前往 Google Cloud 控制台,依序點選「Load balancing」(負載平衡)>「Edit」(編輯)>「Backend configuration」(後端設定)。詳情請參閱「啟用現有後端服務的記錄功能」。該後端服務的記錄取樣率必須設為大於 0.0。
前往 Google Cloud 控制台的「Logs Explorer」頁面,選取正確的專案。
調整日期範圍,涵蓋您懷疑發生問題的期間。詳情請參閱「使用時間範圍選取器」。
如要查看 Google 代碼閘道插入外掛程式處理的要求記錄,請使用下列查詢:
resource.type="http_load_balancer" logName="projects/PROJECT_ID/logs/requests" \ jsonPayload.serviceExtensionInfo.extension="0-google-tag-gateway"
將
PROJECT_ID替換為專案 ID。檢查
jsonPayload.serviceExtensionInfo.perProcessingRequestInfo.grpcStatus欄位,找出潛在錯誤。這裡會顯示 Google 代碼閘道擴充功能本身的狀態。OK:擴充功能已完成處理,未發生 gRPC 錯誤。OK以外的任何值 (例如INTERNAL、UNAVAILABLE、DEADLINE_EXCEEDED):表示執行 Google 代碼閘道擴充功能時發生錯誤。
如要找出 Google 代碼閘道擴充功能回報錯誤的記錄,請使用下列查詢:
resource.type="http_load_balancer" logName="projects/PROJECT_IDlogs/requests" \ jsonPayload.serviceExtensionInfo.extension="0-google-tag-gateway" NOT jsonPayload.serviceExtensionInfo.perProcessingRequestInfo.grpcStatus="OK"
上述查詢傳回結果後,請檢查整個記錄項目,將擴充功能狀態與要求結果建立關聯:
- Google 代碼閘道擴充功能失敗:如果
grpcStatus不是OK(特別是在RESPONSE_BODY事件上),表示代碼插入程序發生錯誤。特定 gRPC 程式碼會提供線索 (例如DEADLINE_EXCEEDED表示逾時)。 - 對使用者要求的影響:如果 Google 代碼閘道擴充功能的
grpcStatus不是OK,請檢查同一記錄項目中的httpRequest.status和jsonPayload.statusDetails。舉例來說,如果非OKgrpcStatus搭配httpRequest.status: 500和jsonPayload.statusDetails: service_extensions_error,表示 Google 代碼閘道擴充功能失敗,導致使用者收到伺服器錯誤。 - 問題頻率:分析這些錯誤記錄的時間戳記和頻率,有助於判斷 Google 代碼閘道插入問題是持續發生、間歇發生,還是與特定事件有關。
- Google 代碼閘道擴充功能失敗:如果
如果在設定過程中遇到問題,且無法透過說明文件解決,請與 Google Ads 支援團隊聯絡。