本頁內容適用於 Apigee 和 Apigee Hybrid。
查看
Apigee Edge 說明文件。
這本劇本可用於診斷及解決 Apigee 和 Apigee Hybrid 的 502 Bad Gateway Unexpected EOF 錯誤。
問題
用戶端應用程式會收到 HTTP 狀態碼 502,以及「Bad Gateway」訊息,做為 API 呼叫的回應。HTTP 狀態碼 502 表示用戶端 (在本例中為 Apigee) 未從後端伺服器收到有效回應,而後端伺服器實際上應滿足要求。
錯誤訊息
用戶端應用程式 API 呼叫遇到下列回應代碼:
HTTP/1.1 502 Bad Gateway
此外,您可能會看到下列錯誤訊息:
{
"fault": {
"faultstring": "Unexpected EOF at target",
"detail": {
"errorcode":"messaging.adaptors.http.flow.UnexpectedEOFAtTarget",
"reason":"TARGET_READ_UNEXPECTED_EOF"
}
}
}常見的診斷步驟
如要診斷錯誤,可以使用下列任一方法:
- API Monitoring
- 偵測工作階段錯誤
- 輸入記錄
- 執行階段記錄檔
API Monitoring
使用 API 監控功能診斷錯誤。
在 Google Cloud 控制台中,前往「Apigee」>「Proxy 開發」>「API 監控」頁面。
在「API monitoring」(API 監控) 頁面中,按照下列步驟調查 502 錯誤:
- 在客戶專案的 Apigee UI 中,前往「Investigate」資訊主頁。
- 在頂端的「圖表」下拉式選單中,確認已選取「依狀態碼顯示錯誤代碼」和「依 Proxy 顯示錯誤來源」,並確認選取 502 錯誤發生時的正確時間範圍。
- 如果看到大量 502 錯誤,請按一下矩陣中的方塊。
- 右側會顯示 502 錯誤的詳細資料,如下所示:
這裡會顯示以下資訊:
- 故障代碼為
messaging.adaptors.http.flow.UnexpectedEOFAtTarget - 故障來源為
target
這表示目標發生非預期的 EOF,導致 502 錯誤。
偵測工作階段錯誤
使用偵錯工作階段診斷錯誤:
- 在進行 API 呼叫時執行新的偵錯工作階段,重現 502 Bad Gateway 錯誤。
- 選取其中一個失敗的要求,然後檢查追蹤記錄。
- 瀏覽追蹤記錄的各個階段,找出發生失敗的位置。
- 要求傳送至目標伺服器後,您應該會看到失敗訊息,如下所示 (請注意,螢幕截圖是偵錯 v1):
如上圖所示,請在發生錯誤的階段檢查 error 屬性。值應包含「Unexpected EOF at target」訊息。
您也可以在追蹤記錄的 AX (Analytics Data Recorded) 階段中,判斷 X-Apigee.fault-source 和 X-Apigee.fault-code 的值。如果 X-Apigee.fault-source 和 X-Apigee.fault-code 的值與下表顯示的值相符,則可確認 502 錯誤來自目標伺服器:
| 回應標頭 | 值 |
|---|---|
| fault-source | target |
| 錯誤碼 | messaging.adaptors.http.flow.UnexpectedEOFAtTarget |
Istio Ingressgateway 記錄 (僅限混合式)
如要診斷 502 Unexpected EOF at target 錯誤,另一種方法是檢查 Ingress 記錄中的 502 錯誤。傳入記錄應顯示 x_apigee_fault_code 的值為 messaging.adaptors.http.flow.UnexpectedEOFAtTarget,而 x_apigee_fault_source 的值為 target。
可能原因
502 Bad Gateway 錯誤的常見原因是 Unexpected EOF 錯誤,可能原因如下:
| 原因 | 說明 |
|---|---|
| 目標伺服器設定有誤 | 目標伺服器未正確設定,無法在 Apigee 中支援傳輸層安全標準 (TLS)/安全資料傳輸層 (SSL) 連線 |
| 後端突然關閉連線 | Apigee 傳送資料或等待後端伺服器回應時,後端伺服器可能會突然關閉連線 |
| Keep-alive 超時設定有誤 | Apigee 和後端伺服器上的 Keep-Alive 超時設定有誤 |
| 搭配使用 NAT 與 AWS NLB 目標,並啟用跨可用區負載平衡和 IP 保留功能 | (僅限 Apigee X) 使用 NAT 搭配 AWS NLB 目標,並啟用跨可用區負載平衡和 IP 保留功能。 |
原因:目標伺服器設定錯誤
目標伺服器未正確設定,無法支援 TLS/SSL 連線。
診斷
- 如果失敗的 API 要求的偵錯工作階段顯示以下內容,很可能是目標伺服器設定有誤導致這個問題:
- 目標流程要求啟動後,隨即出現 502 Bad Gateway 錯誤
error.class會顯示messaging.adaptors.http.flow.UnexpectedEOF
{ "properties": { "error.class": "messaging.adaptors.http.flow.UnexpectedEOF", "error.cause": "java.io.EOFException: eof unexpected" } }{ "properties": { "error.class": "messaging.adaptors.http.flow.UnexpectedEOF", "error.cause": "java.io.EOFException: eof unexpected" } } - 使用 Apigee 管理 API 呼叫取得目標伺服器定義
export TOKEN=$(gcloud auth print-access-token);
curl -s -H "Authorization: Bearer $TOKEN" https://apigee.googleapis.com/v1/organizations/{org_name}/environments/{env_name}/targetservers/{target_server}錯誤的 TargetServer 定義範例:
{
"name": "bad-targetserver",
"host": "my-apigee-example.sample.appspot.com",
"port": 443,
"isEnabled": true,
"protocol": "HTTP"
}圖示 TargetServer 定義是常見的設定錯誤範例,說明如下:
假設目標伺服器 my-apigee-example.sample.appspot.com 已設為接受通訊埠 443 的安全 (HTTPS) 連線。不過,如果您查看目標伺服器定義,會發現沒有其他屬性/旗標指出該伺服器適用於安全連線。這會導致 Apigee X 將傳送至特定目標伺服器的 API 要求視為 HTTP (不安全) 要求。因此 Apigee X 不會啟動與這個目標伺服器的 TLS/SSL 握手程序。
由於目標伺服器已設定為僅接受通訊埠 443 上的 HTTPS (TLS/SSL) 要求,因此會拒絕 Apigee X 的要求或關閉連線。因此 apigee-runtime 會顯示 UnexpectedEOFAtTarget 錯誤。apigee-runtime 會將 502 Bad Gateway 做為回應傳送給用戶端。
解析度
請務必根據需求正確設定目標伺服器。以上圖示範例中,如要向安全 (HTTPS TLS/SSL) 目標伺服器發出要求,您需要加入 sSLInfo 屬性,並將 enabled 旗標設為 true。雖然可以在目標端點定義中新增目標伺服器的 sSLInfo 屬性,但建議您將 SSLInfo 屬性新增為目標伺服器定義的一部分,以免造成混淆。您可以直接在目標伺服器上啟用所有必要屬性,如下所示:
「更新目標伺服器」對話方塊,並開啟「啟用 SSL」切換按鈕。如果後端服務需要單向 SSL 通訊,您必須在目標伺服器定義中啟用 TLS/SSL,方法是加入 sSLInfo 屬性,並將 enabled 旗標設為 true。用來取得目標伺服器的 API 呼叫應會傳回如下所示的資料:
{
"name": "bad-targetserver",
"host": "my-apigee-example.sample.appspot.com",
"port": 443,
"isEnabled": true,
"sSLInfo": {
"enabled": true
},
"protocol": "HTTP"
}如果需要在 Apigee X 中驗證目標伺服器的憑證,則必須一併加入包含目標伺服器憑證的 truststore,如下所示:
{
"name": "bad-targetserver",
"host": "my-apigee-example.sample.appspot.com",
"port": 443,
"isEnabled": true,
"sSLInfo": {
"enabled": true,
"trustStore": "ref://my-reference"
},
"protocol": "HTTP"
}如果後端服務需要雙向 SSL 通訊,則您需要適當設定 sSLInfo 屬性的 clientAuthEnabled、keystore、keyAlias 和 truststore 旗標,如下所示:
{
"name": "bad-targetserver",
"host": "my-apigee-example.sample.appspot.com",
"port": 443,
"isEnabled": true,
"sSLInfo": {
"enabled": true,
"clientAuthEnabled": true,
"keyStore": "ref://test-ref",
"keyAlias": "my-alias-2",
"trustStore": "ref://my-reference"
},
"protocol": "HTTP"
}原因:後端突然關閉連線
建立 TCP 連線後,後端伺服器可能會在 Apigee 傳送資料或等待回應時突然關閉連線,進而觸發 Apigee 執行階段的 EOF 例外狀況。
診斷
如「常見診斷步驟」所示,使用 API 監控、偵錯工作階段或 Ingress 記錄,判斷 502 錯誤的訊息 ID、錯誤代碼和錯誤來源。
以下記錄是 Istio Gateway 記錄的範例 (僅限混合式),當後端突然關閉連線時就會建立這類記錄 (範例已稍微縮短)。請特別注意例外狀況 x_apigee_fault_code、target 和包含 HTTP 502 狀態碼的 status:UnexpectedEOFAtTargetx_apigee_fault_source
{
"dynamic_data": {
"x_apigee_fault_flag": "false",
"x_apigee_target_latency": "3335",
"x_apigee_dp_color": "1-11-0-apigee-8",
"x_apigee_fault_revision": "/organizations/test-org/environments/test-env/apiproxies/eof-test/revisions/5",
"x_apigee_fault_code": "messaging.adaptors.http.flow.UnexpectedEOFAtTarget",
"x_apigee_tracking_id": "b65eb01ec690656918d39cc767eb6aad",
"x_apigee_organization": "test-org",
"x_apigee_fault_source": "target",
"x_apigee_message_id": "123abc45-6def-789a-bc1-23def456abc78",
"x_envoy_upstream_service_time": "3558",
"x_apigee_region": "us-east1",
"x_apigee_fault_policy": "null/null",
"x_apigee_environment": "test-env",
"x_apigee_proxy": "/organizations/test-org/environments/test-env/apiproxies/eof-test/revisions/5",
"x_apigee_proxy_basepath": "/eof-test"
},
"start_time": "2023-12-13T07:08:03.054Z",
"request_time": 3562,
"host": "203.0.113.10.nip.io",
"request_method": "GET",
"apigee_tracking_id": "b65eb01ec690656918d39cc767eb6aad",
"upstream_address": "10.1.1.2:8443",
"status": 502,
"upstream_response_time": 3560,
"x_forwarded_for": "198.51.100.10,203.0.113.10,198.51.100.11",
"request_protocol": "HTTP/1.1",
"status_details": "via_upstream",
"remote_address": "192.0.2.10:45752",
"tls_protocol": "TLSv1.2",
"request_id": "ce871b05-e62d-44a9-b15d-cb2f3553fd7f",
"bytes_received": 0,
"upstream_response_flags": "-"
}記下 Istio Gateway 記錄中的 x_apigee_message_id( 僅限 Hybrid),或從其他來源 (例如偵錯工作階段) 取得 message_id,然後檢查 apigee-runtime 記錄( 僅限 Hybrid) 中的 502 Istio 記錄。
下列範例記錄顯示 java.io.EOFException:
{
"insertId": "2xo6ibes68n88g38",
"jsonPayload": {
"level": "SEVERE",
"logger": "HTTP.CLIENT",
"className": "com.apigee.protocol.http.HTTPClient$Context$3",
"message": "ClientChannel[Connected: Remote:203.0.113.20:8080 Local:10.1.1.2:25480]@148915 useCount=0 bytesRead=0 bytesWritten=1303 age=3334ms lastIO=3163ms isOpen=true.onExceptionRead",
…
"thread": "NIOThread@0",
"exceptionStackTrace": "java.io.EOFException: eof unexpected\n\tat com.apigee.nio.channels.PatternInputChannel.doRead(PatternInputChannel.java:31)\n\tat com.apigee.nio.channels.InputChannel.read(InputChannel.java:95)\n\tat com.apigee.protocol.http.io.MessageReader.onRead(MessageReader.java:87)\n\tat com.apigee.nio.channels.DefaultNIOSupport$DefaultIOChannelHandler.onIO(DefaultNIOSupport.java:44)\n\tat com.apigee.nio.handlers.NIOThread.run(NIOThread.java:195)\n",
"method": "onException"
},
…
}
在上述範例中,您可以看到 apigee-runtime 嘗試從後端伺服器讀取回應時發生 java.io.EOFException: eof unexpected 錯誤。這項例外狀況表示檔案結尾 (EOF),或意外達到串流結尾。
這表示 apigee-runtime 已成功連線至後端伺服器,且正在傳送 API 要求,或正在等待或讀取後端的回應。不過,後端伺服器因某種原因突然終止連線,導致 apigee-runtime 無法取得預期回應或讀取完整回應。
如要取得後端伺服器突然終止連線的最終證明,請執行下列操作:
- 通常,當 apigee-runtime 將要求傳送至後端伺服器時,後端伺服器會立即以
[FIN,ACK]回應,因而導致這項錯誤。查看後端伺服器記錄,瞭解是否有任何錯誤或資訊,導致後端伺服器突然終止連線。如果發現任何錯誤/資訊,請前往「解決方法」,並在後端伺服器中適當修正問題。如果後端伺服器中沒有任何錯誤或資訊,請在 Apigee 之後的第一個躍點收集封包擷取。 - (僅限混合式) 您可能也想在 apigee-runtime 上收集封包擷取內容,請參閱「如何擷取 tcpdump」一文。如果是 GKE,請參閱 https://cloud.google.com/container-optimized-os/docs/how-to/toolbox。
- 請參考以下 tcpdump 範例。以下是發生 502 Bad Gateway Error UnexpectedEOFAtTarget 時擷取的 tcpdump 範例:
後端過早傳送 FIN、ACK 的 tcpdump 範例。 - 從 TCPDump 輸出內容中,您會發現下列事件順序:
- 封包 2354 到 2372 成功建立 apigee-runtime 與後端伺服器之間的連線。
- 在封包 2512 中,後端伺服器會以 [FIN,ACK] 回應 (封包 2372 從 Apigee 傳送至封包 2512 的 [FIN, ACK] 之間經過 3 秒,是因為這個範例是在後端休眠 3 秒後建構,之後就會關閉連線)。
- 在封包 2516 中,apigee-runtime 會以 [FIN,ACK] 回應後端伺服器。
- 最終,連線會由 Apigee 以 [RST] 關閉。
- 由於 Apigee 仍在傳送要求,或等待 / 讀取後端伺服器的回應,因此後端伺服器突然傳送 [FIN,ACK] 時,Apigee 會擲回
java.io.EOFException: eof unexpected例外狀況,因為 Apigee 預期不會收到這類訊息。
解析度
請注意,這並非一般的連線逾時錯誤 (狀態碼 503),因為 TCP 連線已成功建立,也不是服務無法使用錯誤 (狀態碼 504),因為連線已透過後端的 [FIN, ACK] 成功關閉 (雖然 apigee-runtime 此時並未預期收到 [FIN, ACK])。如果後端伺服器發生網路問題,或是後端程式碼有錯誤,就可能發生這種情況。顧客需要請網路營運團隊和後端伺服器團隊進一步調查這個問題,並在後端伺服器或網路躍點上適當修正問題。
原因:存留逾時設定有誤
在判斷 502 錯誤是否由這個原因造成之前,請先詳閱下列概念。
Apigee 中的永久連線
根據預設,Apigee X 會遵循 HTTP/1.1 標準,並在與目標後端伺服器通訊時使用持續性連線。持續性連線可重複使用已建立的 TCP 和 (如適用) TLS/SSL 連線,藉此減少延遲負擔,進而提升效能。連線需要保留的時間長度,是透過存留時間逾時屬性 (在 Apigee 的目標端點設定中,這個屬性稱為 keepalive.timeout.millis) 控制。
後端伺服器和 Apigee apigee-runtime 都會使用保持連線逾時,彼此保持連線。如果超過存留時間逾時期間未收到任何資料,後端伺服器或 apigee-runtime 即可關閉與對方的連線。
根據預設,部署至 Apigee X 中 apigee-runtime 的 API Proxy 會將連線存留逾時設為 60 秒,除非遭到覆寫。如果 60 秒內未收到任何資料,Apigee 就會關閉與後端伺服器的連線。後端伺服器也會維持保持連線逾時,一旦逾時,後端伺服器就會關閉與 apigee-runtime 的連線。
Keepalive 超時設定有誤的影響
如果 Apigee 或後端伺服器設定的保持連線逾時時間不正確,就會導致競爭條件,後端伺服器會傳送非預期的檔案結尾 (FIN),以回應資源要求。
舉例來說,如果 API Proxy 或 apigee-runtime 內設定的連線存留逾時值大於或等於上游後端伺服器的逾時值,則可能會發生下列競爭條件。也就是說,如果 apigee-runtime 在後端伺服器保持連線逾時的門檻附近才收到資料,但要求會透過現有連線傳送至後端伺服器,則可能因非預期的 EOF 錯誤而導致 502 Bad Gateway,說明如下:
- 假設在 apigee-runtime 和後端伺服器上設定的連線存續逾時時間為 60 秒,且特定 apigee-runtime 處理上一個要求後,59 秒內沒有收到任何新要求。
- apigee-runtime 會繼續使用現有連線處理第 59 秒傳入的要求 (因為保持連線逾時尚未經過),並將要求傳送至後端伺服器。
- 不過,要求抵達後端伺服器之前,後端伺服器已超過連線存留逾時門檻。
- apigee-runtime 對資源的要求正在傳輸中,但後端伺服器嘗試傳送 FIN 封包至 apigee-runtime,藉此關閉連線。
- apigee-runtime 等待接收資料時,卻收到非預期的 FIN,因此連線遭到終止。
- 這會導致 Unexpected EOF,隨後 apigee-runtime 會將 502 錯誤傳回給用戶端。
在本例中,我們發現發生 502 錯誤的原因是 apigee-runtime 和後端伺服器都設定了相同的 60 秒存留時間逾時值。同樣地,如果 apigee-runtime 上設定的連線存留逾時值高於後端伺服器,也可能發生這個問題。
診斷
如「常見診斷步驟」所示,使用 API 監控、偵錯工作階段或 Ingress 記錄,判斷 502 錯誤的訊息 ID、錯誤代碼和錯誤來源。
以下記錄是 Istio Gateway 記錄的範例 (僅限混合式),當後端突然關閉連線時就會建立這類記錄 (範例已稍微縮短)。請特別注意例外狀況 x_apigee_fault_code、target 和包含 HTTP 502 狀態碼的 status:UnexpectedEOFAtTargetx_apigee_fault_source
{
...
"dynamic_data": {
"x_apigee_fault_flag": "false",
"x_apigee_target_latency": "3335",
"x_apigee_dp_color": "1-11-0-apigee-8",
"x_apigee_fault_revision": "/organizations/my-org/environments/test-env/apiproxies/eof-test/revisions/5",
"x_apigee_fault_code": "messaging.adaptors.http.flow.UnexpectedEOFAtTarget",
"x_apigee_tracking_id": "b65eb01ec690656918d39cc767eb6aad",
"x_apigee_organization": "my-org",
"x_apigee_fault_source": "target",
"x_apigee_message_id": "951a6d91-1c83-4cd0-bd0d-5d69d0310b1e1",
"x_envoy_upstream_service_time": "3558",
"x_apigee_region": "us-east1",
"x_apigee_fault_policy": "null/null",
"x_apigee_environment": "test-env",
"x_apigee_proxy": "/organizations/my-org/environments/test-env/apiproxies/eof-test/revisions/5",
"x_apigee_proxy_basepath": "/eof-test"
},
"start_time": "2023-12-13T07:08:03.054Z",
"request_time": 3562,
"host": "203.0.113.10.nip.io",
"request_method": "GET",
"apigee_tracking_id": "b65eb01ec690656918d39cc767eb6aad",
"upstream_address": "10.1.1.2:8443",
"status": 502,
"upstream_response_time": 3560,
"x_forwarded_for": "198.51.100.10,203.0.113.10,198.51.100.11",
"request_protocol": "HTTP/1.1",
"status_details": "via_upstream",
"remote_address": "192.0.2.10:45752",
"tls_protocol": "TLSv1.2",
"request_id": "ce871b05-e62d-44a9-b15d-cb2f3553fd7f",
"bytes_received": 0,
"upstream_response_flags": "-"
},
"resource": {
...
}
},
"timestamp": "2023-12-13T07:08:06.867811686Z",
"severity": "INFO",
"labels": {
..
},
...
}記下 Istio Gateway 記錄中的 x_apigee_message_id( 僅限 Hybrid),或從其他來源 (例如偵錯工作階段) 取得 message_id,然後檢查 apigee-runtime 記錄( 僅限 Hybrid) 中的 502 Istio 記錄。您可以將 Istio 記錄檔與 apigee-runtime 記錄檔比對。對 Apigee Runtime 的查詢會顯示類似下列內容的記錄:
下列記錄範例顯示 java.io.EOFException
{
"insertId": "2xo6ibes68n88g38",
"jsonPayload": {
"level": "SEVERE",
"logger": "HTTP.CLIENT",
"className": "com.apigee.protocol.http.HTTPClient$Context$3",
"message": "ClientChannel[Connected: Remote:203.0.113.20:8080 Local:10.1.1.2:25480]@148915 useCount=7 bytesRead=0 bytesWritten=1303 age=3334ms lastIO=3163ms isOpen=true.onExceptionRead",
…
"thread": "NIOThread@0",
"exceptionStackTrace": "java.io.EOFException: eof unexpected\n\tat com.apigee.nio.channels.PatternInputChannel.doRead(PatternInputChannel.java:31)\n\tat com.apigee.nio.channels.InputChannel.read(InputChannel.java:95)\n\tat com.apigee.protocol.http.io.MessageReader.onRead(MessageReader.java:87)\n\tat com.apigee.nio.channels.DefaultNIOSupport$DefaultIOChannelHandler.onIO(DefaultNIOSupport.java:44)\n\tat com.apigee.nio.handlers.NIOThread.run(NIOThread.java:195)\n",
"method": "onException"
},
…
}
}錯誤 java.io.EOFException: eof unexpected 表示 apigee-runtime 收到 EOF,但仍在等待讀取後端伺服器的回應。
錯誤訊息中的 useCount=7 屬性表示 apigee-runtime 已重複使用此連線約七次,而 bytesWritten=1303 屬性則表示 apigee-runtime 已將 1303 位元組的要求酬載傳送至後端伺服器。但發生非預期的 EOF 錯誤時,系統會收到零位元組。
這表示 apigee-runtime 多次重複使用相同連線,且這次傳送資料後不久,就收到 EOF,但未收到任何資料。這表示後端伺服器的連線存續逾時時間,很可能短於或等於 API Proxy 中設定的時間。
您可以按照下文說明,使用 tcpdump 進一步調查。
- 如果後端伺服器中沒有任何錯誤或資訊,請在 Apigee 之後的第一個躍點上收集封包擷取,方法是執行下列指令:
tcpdump -i any -s 0 host <BACKEND_HOSTNAME> -w <FILENAME>
- (僅限混合式) 您可能也想在 apigee-runtime 上收集封包擷取內容,請參閱「如何擷取 tcpdump」一文。如果是 GKE,請參閱 https://cloud.google.com/container-optimized-os/docs/how-to/toolbox。
- 分析擷取的 tcpdump:
在上述 tcpdump 範例中,您可以看到下列內容:
- 在封包 5992 中,後端伺服器收到 GET 要求。
- 在封包 6064 中,伺服器會以 200 OK 回應。
- 在封包 6084 中,後端伺服器收到另一個 GET 要求。
- 在封包 6154 中,伺服器會以 200 OK 回應。
- 在封包 6228 中,後端伺服器收到第三個 GET 要求。
- 這次,後端伺服器會將 FIN、ACK 傳回 apigee-runtime (封包 6285),啟動連線關閉程序。
在本範例中,同一個連線成功重複使用兩次,但在第三個要求中,後端伺服器啟動連線關閉程序,而 apigee-runtime 正在等待後端伺服器的資料。這表示後端伺服器的連線存留逾時時間,很可能短於或等於 API Proxy 中設定的值。
比較 Apigee 和後端伺服器上的 Keep-Alive 超時
- 根據預設,Apigee X 會將連線存留逾時屬性的值設為 60 秒。
- 不過,客戶可能已在 API Proxy 中覆寫預設值。如要確認這項問題,請檢查發生 502 錯誤的 API Proxy 中,特定 TargetEndpoint 的定義。以下是 TargetEndpoint 設定範例,其中「keep alive timeout」屬性已覆寫為 30 秒 (30000 毫秒):
- 接著,請檢查後端伺服器上設定的「保持連線逾時」屬性。假設後端伺服器設定的值為 25 秒。
- 如果您判斷 Apigee 的保持連線逾時屬性值高於後端伺服器的保持連線逾時屬性值 (如上例所示),這就是導致 502 錯誤的原因。
<TargetEndpoint name="default">
<HTTPTargetConnection>
<URL>https://mocktarget.apigee.net/json</URL>
<Properties>
<Property name="keepalive.timeout.millis">30000</Property>
</Properties>
</HTTPTargetConnection>
</TargetEndpoint>解析度
請務必確保 Apigee (在 API Proxy 和 apigee-runtime 元件中) 的連線存留逾時屬性,一律低於後端伺服器上的屬性。
- 判斷後端伺服器上設定的連線存留逾時值。
- 在 API Proxy 或 apigee-runtime 中,為保持運作逾時屬性設定適當的值,使保持運作逾時屬性低於後端伺服器上設定的值,方法請參閱「反模式:停用 HTTP 持續性 (可重複使用的保持運作) 連線」一文。
原因:搭配使用 NAT 與 AWS NLB 目標,並啟用跨區域負載平衡和 IP 保留功能
(僅限 Apigee X) 如果您使用 AWS NLB 做為目標,可能會遇到下列問題:
假設 AWS NLB 有 3 個 IP:
203.0.113.1:443 (可用區 1)
203.0.113.2:443 (可用區 2)
203.0.113.3:443 (可用區 3)
Apigee X 會建立下列連線:
- 192.0.2.10:30009 -> 203.0.113.1:443
- 192.0.2.10:30009 -> 203.0.113.1:443 (現有)
- 192.0.2.10:30009 -> 203.0.113.2:443 (new)
這是正常現象。
如果 203.0.113.1:443 和 203.0.113.2:443 指向相同的 NLB 後端,就會發生問題。如果是,後端會收到來自相同來源,但屬於兩個不同連線的封包。這會導致兩項連結都中斷。
第一次連線可能會失敗,並出現相同的 EOF 錯誤,但也有可能出現其他錯誤。
診斷
確認是否符合所有下列條件:
如果是這樣,問題應該會間歇性發生。由於上述條件可診斷問題,因此不需要 .pcap。不過,您可以在目標網路擷取中發現,但無法在 Apigee 擷取中發現。
目標 .pcap 診斷
如要在 Wireshark 的目標擷取畫面中找出這項資訊,請按照下列步驟操作:
- 依受影響連線的通訊埠篩選,例如 tcp.port == 30009
- 在「資料欄」上按一下滑鼠右鍵 ->「資料欄偏好設定」。新增「自訂」類型的欄。欄位:tcp.seq_raw。系統會顯示原始序號。
- 找出具有 Apigee 來源 IP 的封包是否有任何新的序號。舉例來說,如果看到以 384 開頭的原始序號,但突然切換為 376,且沒有有效的連接埠重複使用案例,就是連線衝突。
解析度
Cloud NAT 在這裡的行為正確,這是 NLB 架構的問題。Apigee 無法進行任何變更。
必須收集診斷資訊
如果按照上述指示操作後問題仍未解決,請收集下列診斷資訊,然後與 Google Cloud 客服團隊聯絡
- Google Cloud 專案 ID
- Apigee 組織
- API Proxy 和修訂版本
- 下載失敗 API 呼叫的偵錯工作階段檔案。
- 與失敗時間相應的後端伺服器記錄。
- 失敗期間,從訊息處理器或後端伺服器擷取的
tcpdump封包。