您正在查看 Apigee Edge 說明文件。
前往 Apigee X 說明文件。info
問題
用戶端應用程式會收到 504
的 HTTP 狀態碼,並在訊息 Gateway Timeout
中回應 API 呼叫。
HTTP 狀態碼 - 504 Gateway Timeout
錯誤表示在執行 API 期間,用戶端未及時收到 Edge Gateway 或後端伺服器的回應
錯誤訊息
用戶端應用程式會取得下列回應碼:
HTTP/1.1 504 Gateway Timeout
在某些情況下,您可能也會看到下列錯誤訊息:
{ "fault": { "faultstring": "Gateway Timeout", "detail": { "errorcode": "messaging.adaptors.http.flow.GatewayTimeout" } } }
閘道逾時的原因為何?
透過 Edge 平台提出 API 要求的一般路徑為「Client -> Router -> Message Processor -> Backend Server」,如下圖所示:
Edge 平台中的用戶端應用程式、路由器和訊息處理器都已設定適當的逾時值。Edge 平台預期為每個 API 要求在一段時間內依據逾時值傳送回應。如果您未在指定時間內收到回應,系統會傳回 504 Gateway Timeout Error
。
下表詳細列出 Edge 中可能逾時的時間:
逾時發生 | 詳細資料 |
---|---|
訊息處理器發生逾時 |
|
路由器發生逾時 |
|
用戶端應用程式發生逾時 |
|
可能原因
在 Edge 中,504 Gateway Timeout
錯誤的常見原因如下:
原因 | 詳細資料 | 給予的步驟 |
---|---|---|
後端伺服器速度緩慢 | 處理 API 要求的後端伺服器因負載過高或效能不佳而速度過慢。 | 公有雲和私有雲使用者 |
Edge 處理 API 要求的速度緩慢 | 由於負載過高或效能不佳,Edge 需要花費很長的時間處理 API 要求。 |
後端伺服器速度緩慢
如果後端伺服器速度非常緩慢,或是處理 API 要求的時間過長,您會收到 504 Gateway Timeout
錯誤。如上一個部分所述,在下列任一情況下,可能會發生逾時情形:
- 訊息處理工具在後端伺服器回應前就逾時。
- 路由器在訊息處理器/後端伺服器回應前就逾時。
- 在 Router/Message Processor/後端伺服器回應前,用戶端應用程式就逾時。
以下各節將說明如何在上述各個情況下診斷及解決問題。
情境 #1:訊息處理工具在後端伺服器回應前逾時
診斷
您可以使用以下程序診斷是否發生 504 Gateway Timeout
錯誤,原因是後端伺服器速度緩慢。
使用追蹤記錄程序 1
如果問題仍未解決 (504
錯誤仍持續發生),請按照下列步驟操作:
- 在 Edge UI 中追蹤受影響的 API。請等待錯誤發生,或如果您有 API 呼叫,請發出一些 API 呼叫,並重現
504 Gateway Timeout
錯誤。 - 發生錯誤後,請檢查顯示回應碼為
504
的特定要求。 - 查看各階段的經過時間,並記下花費最多時間的階段。
- 如果您在下列任一階段後立即發現錯誤,且該錯誤的經過時間最長,表示後端伺服器速度緩慢,或需要很長的時間才能處理要求:
- 要求已傳送至目標伺服器
- ServiceCallout 政策
以下提供追蹤記錄範例,顯示後端伺服器在 55 秒後仍未回應,導致 504 Gateway Timeout
錯誤:
在上述追蹤記錄中,「訊息處理器」會在 55002 毫秒後逾時,因為後端伺服器沒有回應。
步驟 2:使用訊息處理工具記錄
- 查看訊息處理器的記錄 (
/opt/apigee/var/log/edge-message-processor/logs/system.log
) -
如果您在特定時間點發現特定 API Proxy 要求的
Gateway Timeout
和onTimeoutRead
錯誤,表示訊息處理器已逾時。顯示閘道逾時錯誤的訊息處理器記錄示例
2015-09-29 20:16:54,340 org:myorg env:staging api:profiles rev:13 NIOThread@1 ERROR ADAPTORS.HTTP.FLOW - AbstractResponseListener.onException() : AbstractResponseListener.onError(HTTPResponse@4d898cf1, Gateway Timeout) 2015-09-29 20:16:57,361 org:myorg env:staging api:profileNewsletters rev:8 NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context$3.onTimeout() : SSLClientChannel[C:XX.XX.XX.XX:443 Remote host:192.168.38.54:38302]@120171 useCount=2 bytesRead=0 bytesWritten=824 age=55458ms lastIO=55000ms .onTimeoutRead
在上述 Message Processor 記錄中,您會發現以 IP 位址 XX.XX.XX.XX 表示的後端伺服器在 55 秒後仍未回應 (lastIO=55000ms)。因此,訊息處理器已逾時,並傳送
504 Gateway Timeout
錯誤。請查看這篇文章:如何在 Message Processor 上控制逾時時間?
- 如何在訊息處理工具上控制逾時時間。訊息處理器通常會透過
HTTPTransport.io.timeout.millis
屬性,設定 預設逾時值 (55 秒)。此逾時值適用於所有屬於由此訊息處理器服務的機構的 API Proxy。- 如果後端伺服器未在 55 秒內回應,訊息處理器就會逾時,並將
504 Gateway Timeout
錯誤傳送至用戶端。
- 如果後端伺服器未在 55 秒內回應,訊息處理器就會逾時,並將
- 訊息處理器中指定的逾時值,可以由 API Proxy 中指定的屬性
io.timeout.millis
覆寫。這個逾時值適用於指定上述屬性的特定 API Proxy。舉例來說,如果在 API Proxy 中將io.timeout.millis
設為 10 秒,則會為這個特定 API Proxy 使用 10 秒的逾時值。- 如果後端伺服器未在 10 秒內回應特定 API Proxy,則訊息處理器會逾時,並傳送
504 Gateway Timeout
錯誤至用戶端。
- 如果後端伺服器未在 10 秒內回應特定 API Proxy,則訊息處理器會逾時,並傳送
- 如何在訊息處理工具上控制逾時時間。訊息處理器通常會透過
解析度
- 查看後端伺服器處理時間超過 55 秒的原因,看看能否加以修正/最佳化,以便更快回應。
- 如果無法修正/最佳化後端伺服器,或是已知後端伺服器花費的時間超過設定的逾時時間,請 將路由器和訊息處理器上的逾時值增加到合適的值。
情境 #2:路由器在訊息處理器/後端伺服器回應前逾時
如果路由器在訊息處理器/後端伺服器回應前逾時,您可能會收到 504 Gateway Timeout
錯誤。以下列舉可能導致這種現象的狀況:
- 路由器上設定的逾時值比訊息處理器上設定的逾時值短。舉例來說,假設路由器的逾時時間是 50 秒,而訊息處理器為 55 秒。
路由器逾時 訊息處理器逾時 50 秒 55 秒 - 使用 API Proxy 目標端點設定內設定的
io.timeout.millis
屬性,將 Message Processor 的逾時值覆寫為較高的逾時值:舉例來說,假設已設定下列逾時值:
路由器逾時 訊息處理器逾時 API Proxy 中的逾時 57 秒 55 秒 120 秒 但在 API Proxy 中,
io.timeout.millis
已設為 120 秒:<HTTPTargetConnection> <Properties> <Property name="io.timeout.millis">120000</Property> </Properties> <URL>http://www.apigee.com</URL> </HTTPTargetConnection>
接著,即使訊息處理工具的逾時值 (55 秒) 小於路由器的逾時值 (57 秒),訊息處理工具也不會在 55 秒後逾時。這是因為 Message Processor 的逾時值 (55 秒) 已由 API Proxy 中設定的 120 秒值覆寫。因此,這個特定 API Proxy 的訊息處理器逾時值將為 120 秒。
由於 Router 的逾時值 (57 秒) 低於 API Proxy 中設定的 120 秒,因此如果後端伺服器在 57 秒後未回應,Router 就會逾時。
診斷
- 查看 NGINX 存取記錄 (
/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
) -
如果路由器在訊息處理器之前逾時,特定 API 要求的 NGINX 存取記錄就會顯示
504
狀態,訊息處理程式的message id
也會設為-
。這是因為 Router 在 Router 上設定的逾時期間內,未收到任何來自 Message Processor 的回應。由於 Router 逾時,因此顯示 504 的 NGINX 記錄項目範例
- 在上述範例中,請注意 NGINX 上的
504
狀態、訊息處理器的訊息 ID 為-
,以及經過的總時間為 57.001 秒。這是因為路由器在 57.001 秒後逾時,我們也未收到任何來自訊息處理器的回應。 - 在這種情況下,訊息處理器記錄中會顯示
Broken Pipe
例外狀況 (/opt/apigee/var/log/edge-message-processor/logs/system.log).
2017-06-09 00:00:25,886 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-mp01-18869-23151-1 NIOThread@1 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception java.io.IOException: Broken pipe occurred while writing to channel ClientOutputChannel(ClientChannel[A:XX.XX.XX.XX:8998 Remote host:YY.YY.YY.YY:51400]@23751 useCount=1 bytesRead=0 bytesWritten=486 age=330465ms lastIO=0ms ) 2017-06-09 00:00:25,887 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-mp01-18869-23151-1 NIOThread@1 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception trace: java.io.IOException: Broken pipe at com.apigee.nio.channels.ClientOutputChannel.writePending(ClientOutputChannel.java:51) ~[nio-1.0.0.jar:na] at com.apigee.nio.channels.OutputChannel.onWrite(OutputChannel.java:116) ~[nio-1.0.0.jar:na] at com.apigee.nio.channels.OutputChannel.write(OutputChannel.java:81) ~[nio-1.0.0.jar:na] … <snipped>
這個錯誤會顯示,因為路由器逾時後,系統會關閉與訊息處理器的連線。訊息處理器完成處理程序後,就會嘗試將回應寫入路由器。由於路由器的連線已關閉,您會在訊息處理器上取得 Broken Pipe exception
。
在上述情況下,您可能會看到這個例外狀況。因此,504 Gateway Timeout
錯誤的實際原因仍是後端伺服器的回應時間過長,您需要解決這個問題。
解析度
- 如果是自訂後端伺服器,請執行以下操作:
- 瞭解後端伺服器回應時間過長的原因,看看能否加以修正/最佳化,以加快回應速度。
- 如果無法修正/最佳化後端伺服器,或是已知後端伺服器需要很長的時間,請提高路由器和訊息處理工具的逾時值。
建議:請按照以下順序設定不同元件的逾時值:
用戶端逾時 > 路由器逾時 > 訊息處理器逾時 > API Proxy 內的逾時
- 如果是 NodeJS 後端伺服器,請執行下列操作:
- 請檢查 NodeJS 程式碼是否會呼叫任何其他後端伺服器,以及是否需要很長的時間才能傳回回應。查看後端伺服器花費較長時間的原因,並視情況修正問題。
- 確認訊息處理器的 CPU 或記憶體用量偏高:
- 如有任何訊息處理器的 CPU 使用率過高,請使用下列指令,每 30 秒產生三個執行緒傾印:
JAVA_HOME/bin/jstack -l PID > FILENAME
- 如果任何 Message Processor 的記憶體使用率偏高,請使用下列指令產生堆積傾印:
sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
- 使用下列指令重新啟動訊息處理器。這個指令應會關閉 CPU 和記憶體:
/opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
- 監控 API 呼叫,確認問題是否已解決。
- 與 Apigee Edge 支援團隊聯絡,並提供執行緒傾印、記憶體快照資料及訊息處理器記錄檔 (
/opt/apigee/var/log/edge-message-processor/logs/system.log)
,協助調查 CPU/記憶體用量偏高的原因。
- 如有任何訊息處理器的 CPU 使用率過高,請使用下列指令,每 30 秒產生三個執行緒傾印:
勾選:如何在訊息處理器上,為 NodeJS 後端伺服器控制逾時
|
情境 #3 - 用戶端應用程式在 Router/Message Processor/後端伺服器回應前逾時
如果用戶端應用程式在後端伺服器回應前逾時,您可能會收到 504 Gateway Timeout
錯誤。發生這種情況的可能原因如下:
- 用戶端應用程式設定的逾時值低於路由器和訊息處理器設定的逾時值:
舉例來說,如果設定下列逾時值:
用戶端逾時 路由器逾時 訊息處理器逾時 50 秒 57 秒 55 秒 在這種情況下,透過 Edge 取得 API 要求回應所需的總時間為 <= 50 秒。這包括提出 API 要求所需的時間、由 Edge (路由器、訊息處理器) 處理的要求、傳送至後端伺服器的要求 (如適用)、後端處理要求並傳送回應、Edge 處理回應,最後將回應傳回用戶端。
如果路由器未在 50 秒內回應用戶端,用戶端就會逾時,並關閉與路由器的連線。用戶端會取得
504
的回應碼。這會讓 NGINX 將狀態碼設為
499
,表示用戶端已關閉連線。
診斷
- 如果用戶端應用程式在收到路由器回應前就逾時,就會關閉與路由器的連線。在這種情況下,您會在特定 API 要求的 NGINX 存取記錄中看到狀態碼 499。
顯示狀態碼 499 的 NGINX 記錄項目範例
- 請注意,在上述範例中,NGINX 上的
499
狀態和總耗時為 50.001 秒。這表示用戶端在 50.001 秒後逾時。 - 在這種情況下,您會在 Message Processor 記錄中看到
Broken Pipe
例外狀況 (/opt/apigee/var/log/edge-message-processor/logs/system.log).
2017-06-09 00:00:25,886 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-1-11193-11467656-1 NIOThread@1 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception java.io.IOException: Broken pipe occurred while writing to channel ClientOutputChannel(ClientChannel[A:XX.XX.XX.XX:8998 Remote host:YY.YY.YY.YY:51400]@23751 useCount=1 bytesRead=0 bytesWritten=486 age=330465ms lastIO=0ms ) 2017-06-09 00:00:25,887 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-1-11193-11467656-1 NIOThread@1 INFO HTTP.SERVICE - ExceptionHandler.handleException() : Exception trace: java.io.IOException: Broken pipe at com.apigee.nio.channels.ClientOutputChannel.writePending(ClientOutputChannel.java:51) ~[nio-1.0.0.jar:na] at com.apigee.nio.channels.OutputChannel.onWrite(OutputChannel.java:116) ~[nio-1.0.0.jar:na] at com.apigee.nio.channels.OutputChannel.write(OutputChannel.java:81) ~[nio-1.0.0.jar:na] … <snipped>
)。 - 路由器逾時後,會關閉與訊息處理器的連線。訊息處理器完成處理作業後,會嘗試將回應寫入 Router。由於與路由器的連線已關閉,您會在訊息處理器上收到
Broken Pipe exception
。 - 在上述情況下,這個例外狀況是預期的結果。因此,
504 Gateway Timeout
錯誤的實際原因仍是後端伺服器回應時間過長,您需要解決這個問題。
解析度
- 如果是自訂後端伺服器,請執行下列操作:
- 請檢查後端伺服器,找出耗時超過 57 秒的原因,並查看是否可以修正/最佳化,以便更快回應。
- 如果無法修正/最佳化後端伺服器,或是您知道後端伺服器會耗費很長的時間,請提高路由器和訊息處理工具的逾時值。
建議:請按照以下順序設定不同元件的逾時值:
用戶端逾時 > 路由器逾時 > 訊息處理器逾時 > API Proxy 中的逾時
- 如果是 NodeJS 後端,請執行以下操作:
- 請檢查 NodeJS 程式碼是否會呼叫任何其他後端伺服器,以及是否需要很長的時間才能傳回。找出後端伺服器耗時較長的原因。
- 檢查 Message Processor 的 CPU 或記憶體用量是否偏高:
- 如果訊息處理器的 CPU 使用率偏高,請使用下列指令,每 30 秒產生三個執行緒傾印:
JAVA_HOME/bin/jstack -l PID > FILENAME
- 如果訊息處理器的記憶體用量偏高,請使用下列指令產生記憶體快照資料:
sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
- 使用下列指令重新啟動訊息處理器。這應該可以降低 CPU 和記憶體:
/opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
- 監控 API 呼叫,確認問題是否已解決。
- 請與 Apigee Edge 支援團隊聯絡,並提供執行緒傾印、堆積傾印和訊息處理器記錄 (
/opt/apigee/var/log/edge-message-processor/logs/system.log)
),協助他們調查 CPU/記憶體使用量偏高的成因。
- 如果訊息處理器的 CPU 使用率偏高,請使用下列指令,每 30 秒產生三個執行緒傾印:
增加 Router 和 Message Processor 的逾時值
請根據您的需求,謹慎選擇要為 Router 和 Message Processor 設定的逾時值。請勿設定過大的逾時值。如需協助,請與 Apigee Edge 支援團隊聯絡。
路由器
chown apigee:apigee /opt/apigee/customer/application/router.properties
- 如果 Router 機器上尚未有
/opt/apigee/customer/application/router.properties
檔案,請建立這個檔案。 - 在這個檔案中新增下列程式碼:
conf_load_balancing_load.balancing.driver.proxy.read.timeout=TIME_IN_SECONDS
舉例來說,如果您想將逾時值設為 120 秒,請按照下列方式設定:
conf_load_balancing_load.balancing.driver.proxy.read.timeout=120
- 確認這個檔案的擁有者是 apigee:
- 重新啟動路由器:
/opt/apigee/apigee-service/bin/apigee-service edge-router restart
- 如果有多部路由器,請在所有路由器上重複執行上述步驟。
訊息處理器
- 如果
/opt/apigee/customer/application/message-processor.properties
檔案尚不存在,請在 Message Processor 機器上建立這個檔案。 - 在這個檔案中新增下列程式碼:
conf_http_HTTPTransport.io.timeout.millis=TIME_IN_MILLISECONDS
舉例來說,如果您想將逾時值設為 120 秒,請按照下列方式設定:
conf_http_HTTPTransport.io.timeout.millis=120000
- 確認這個檔案由 apigee 擁有:
chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
- 重新啟動「訊息處理器」:
/opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
- 如果您有多個訊息處理器,請對所有訊息處理器重複上述步驟。
建議:請按照以下順序設定不同元件的逾時值:用戶端逾時 > 路由器逾時 > 訊息處理器逾時 > API Proxy 中的逾時 |
Edge 處理 API 要求的速度緩慢
如果 Edge 速度非常慢,且/或需要很長的時間才能處理 API 要求,您就會收到 504 Gateway Timeout
錯誤。
診斷
- 在 Edge UI 中追蹤受影響的 API。
- 請等待錯誤發生,或如果您有 API 呼叫,請發出一些 API 呼叫,並重現
504 Gateway Timeout
錯誤。 - 請注意,在這種情況下,您可能會在追蹤記錄中看到成功的回應。
- 由於訊息處理器未在 Router/client 的指定逾時期限內回應 (以較短的逾時期限為準),因此 Router/client 會逾時。但訊息處理器會繼續處理要求,並可能順利完成。
- 此外,只有在訊息處理器與 HTTP/HTTPS 後端伺服器通訊時,訊息處理器上設定的
HTTPTransport.io.timeout.millis
值才會觸發。換句話說,如果 API Proxy 中的任何政策 (ServiceCallout 政策除外) 耗費的時間過長,就不會觸發這項逾時機制。
- 發生錯誤後,請檢查經過時間最長的特定要求。
- 查看各階段的經過時間,並記下花費最多時間的階段。
- 如果您發現服務標示政策以外的任何政策,顯示最長的時間長度,表示 Edge 處理要求的時間過長。
- 以下是 UI 追蹤記錄範例,顯示 JavaScript 政策經過的時間非常長:
- 在上述範例中,您會發現 JavaScript 政策需要約 245 秒的異常長時間。
解析度
- 請檢查政策是否需要很長的時間才能回應,以及是否有任何可能需要很長時間才能處理的自訂程式碼。如果有任何這類程式碼,請嘗試修正/最佳化所識別的程式碼。
- 如果沒有可能導致處理時間過長的自訂程式碼,請檢查訊息處理器的 CPU 或記憶體使用率是否偏高:
- 如果任何 Message Processor 的 CPU 使用率偏高,請使用下列指令,每 30 秒產生三個執行緒傾印:
JAVA_HOME/bin/jstack -l PID > FILENAME
- 如有任何訊息處理器的記憶體用量偏高,請使用下列指令產生記憶體快照資料:
sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
- 使用下列指令重新啟動訊息處理器。這應該會降低 CPU 和記憶體。
/opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
- 監控 API 呼叫,確認問題是否仍然存在。
- 請與 Apigee Edge 支援團隊聯絡,並提供執行緒傾印、堆積傾印和訊息處理器記錄 (
/opt/apigee/var/log/edge-message-processor/logs/system.log)
),協助他們調查 CPU/記憶體使用量偏高的成因。
- 如果任何 Message Processor 的 CPU 使用率偏高,請使用下列指令,每 30 秒產生三個執行緒傾印:
使用 API Monitoring 診斷問題
API 監控功能可讓您快速找出問題所在,診斷錯誤、效能和延遲問題及其來源,例如開發人員應用程式、API Proxy、後端目標或 API 平台。
逐步完成範例情境,瞭解如何使用 API 監控功能,排解 API 的 5xx 問題。比方說,您可以設定快訊,在 504 個狀態碼數量超過特定門檻時收到通知。