504 閘道逾時

您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件
資訊

問題

用戶端應用程式會收到 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」(用戶端) ->「路由器」->「訊息處理器」->「後端伺服器」,如下圖所示:

Edge 平台中的用戶端應用程式、路由器和訊息處理器已妥善設定逾時值。Edge 平台會預期根據逾時值,針對每個 API 要求,在指定時間內傳送回應。如果您未在指定時間範圍內收到回應,則會傳回 504 Gateway Timeout Error

下表詳細說明 Edge 中可能發生逾時的時間:

逾時發生 詳細說明
訊息處理器發生逾時
  • 後端伺服器未在訊息處理器中的指定逾時期間內回應訊息處理器。
  • 訊息處理器逾時,並以 504 Gateway Timeout 的形式將回應傳送至路由器。
路由器發生逾時情形
  • 訊息處理器不會在路由器指定的逾時期限內回應路由器。
  • 路由器逾時,並以 504 Gateway Timeout 的形式將回應狀態傳送至用戶端應用程式。
用戶端應用程式發生逾時
  • 路由器未在路由器指定的逾時期限內回應用戶端應用程式。
  • 用戶端應用程式會逾時,並以 504 Gateway Timeout 的形式結束對使用者的回應狀態。

可能原因

在 Edge 中,504 Gateway Timeout 錯誤的常見原因為:

原因 詳細說明 步入:
後端伺服器速度緩慢 由於負載過高或效能不佳,處理 API 要求的後端伺服器速度過慢。 公有雲與私有雲使用者
Edge 的 API 要求處理速度緩慢 由於負載過高或效能不佳,邊緣需要很長的時間來處理 API 要求。

後端伺服器速度緩慢

如果後端伺服器處理 API 要求的速度非常緩慢,或是處理時間過長,您會收到 504 Gateway Timeout 錯誤。如上一節所述,以下情況可能會發生逾時:

  1. 訊息處理器在後端伺服器回應前逾時。
  2. 訊息處理器/後端伺服器回應前,路由器逾時。
  3. 用戶端應用程式會在路由器/訊息處理器/後端伺服器回應之前逾時。

以下各節說明如何在上述情境中診斷及解決問題。

情境 #1 訊息處理器在後端伺服器回應前逾時

診斷

您可以執行下列程序,診斷 504 Gateway Timeout 錯誤是否因後端伺服器速度變慢而發生。

使用追蹤記錄的程序 1

如果問題仍未解決 (仍有 504 項錯誤),請按照下列步驟操作:

  1. 在 Edge UI 中追蹤受影響的 API。您可以等待錯誤發生,或是如果有 API 呼叫,然後發出一些 API 呼叫並重現 504 Gateway Timeout 錯誤。
  2. 發生錯誤後,請檢查要求回應代碼是否為 504 的特定要求。
  3. 檢查每個階段的經過時間,並記下花費最多時間的階段。
  4. 如果你在下列任一階段後發現經過的最長時間錯誤,表示後端伺服器處理要求的速度緩慢,或處理時間過長:
    • 要求已傳送至目標伺服器
    • 服務摘要政策

下列範例提供的 Trace 範例顯示,即使後端伺服器在 55 秒後沒有回應,也因此產生 504 Gateway Timeout 錯誤:

在上述追蹤記錄中,訊息處理器會在 55002 毫秒後逾時,因為後端伺服器沒有回應。

程序 2 使用訊息處理器記錄

  1. 查看訊息處理器的記錄 (/opt/apigee/var/log/edge-message-processor/logs/system.log)
  2. 如果您在特定時間發現特定 API Proxy 要求的 Gateway TimeoutonTimeoutRead 錯誤,表示訊息處理器已逾時。

    顯示閘道逾時錯誤的訊息處理器記錄檔範例

    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
    

    在上述的訊息處理器記錄中,您注意到後端伺服器表示 IP 位址為 XX.XX.XX.XX,即使在 55 秒之後 (lastIO=55000ms) 也沒有回應。因此,「訊息處理器」逾時並傳送 504 Gateway Timeout 錯誤。

    請檢查是否:如何控制訊息處理器的逾時時間?

    • 如何控制訊息處理器上的逾時時間。訊息處理器通常透過 HTTPTransport.io.timeout.millis 屬性設定預設逾時值 (55 秒)。此逾時值適用於由這個訊息處理器提供之機構的所有 API Proxy。
      • 如果後端伺服器未在 55 秒內回應,則訊息處理器會逾時,並將 504 Gateway Timeout 錯誤傳送至用戶端。
    • 可由 API Proxy 中指定的屬性 io.timeout.millis 覆寫訊息處理器中指定的逾時值。此逾時值適用於已指定上述屬性的特定 API Proxy。舉例來說,如果 io.timeout.millis 在 API Proxy 中設為 10 秒,系統就會將 10 秒的逾時值用於這個特定 API Proxy。
      • 如果後端伺服器未在 10 秒內回應特定 API Proxy,則訊息處理器會逾時,並將 504 Gateway Timeout 錯誤傳送至用戶端。

解析度

  1. 瞭解後端伺服器耗時超過 55 秒的原因,看看是否可進行修正/最佳化以加快回應速度。
  2. 如果您無法修正/最佳化後端伺服器,或已知後端伺服器花費的時間超過設定的逾時時間,請 增加路由器和訊息處理器的逾時值,設為合適的值。

情境 #2 - 訊息處理器/後端伺服器回應前,路由器逾時

如果路由器在訊息處理器/後端伺服器回應之前逾時,你可能會收到 504 Gateway Timeout 錯誤。可能的原因如下:

  • 路由器中設定的逾時值短於訊息處理器中設定的逾時值。舉例來說,假設路由器的逾時時間為 50 秒,而訊息處理器為 55 秒。
    路由器逾時 訊息處理器發生逾時
    50 秒 55 秒
  • 訊息處理器的逾時值會以較高的逾時值覆寫,並覆寫為 API Proxy 目標端點設定內設定的 io.timeout.millis 屬性:

    舉例來說,如果設定了下列逾時值:

    路由器逾時 訊息處理器發生逾時 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 秒後逾時,即使逾時值 (55 秒) 低於路由器的逾時值 (57 秒)。這是因為訊息處理器的逾時值 (55 秒) 會覆寫 API Proxy 中設定的 120 秒值。因此,這個特定 API Proxy 的訊息處理器逾時值是 120 秒。

    比起在 API Proxy 中設定的 120 秒,路由器的逾時值 (57 秒) 較低,因此如果後端伺服器未在 57 秒內回應,路由器就會逾時。

診斷

  1. 查看 NGINX 存取記錄檔 (/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log)
  2. 如果路由器在訊息處理器之前逾時,您會在特定 API 要求的 NGINX 存取記錄檔看見 504 狀態,訊息處理器的 message id 則會設為 -。這是因為路由器未在路由器設定的逾時期限內收到訊息處理器的任何回應。

    因路由器逾時而顯示 504 的 NGINX 記錄項目範例

  3. 在上述範例中,請注意 NGINX 上的 504 狀態,訊息處理器傳送的訊息 ID 為 -,總經過時間為 57.001 秒。這是因為路由器在 57.001 秒後逾時,而且我們無法從訊息處理器收到任何回應。
  4. 在此情況下,訊息處理器記錄檔 (/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 例外狀況

由於路由器逾時,它會關閉與訊息處理器的連線,因此系統顯示這個錯誤。訊息處理器完成處理作業後,會嘗試將回應寫入路由器。由於與路由器的連線已關閉,您會在訊息處理器中取得 Broken Pipe exception

在上述情況中,我們預期會出現這個例外。因此,發生 504 Gateway Timeout 錯誤的實際原因仍是後端伺服器的回應時間較長,您必須處理該項問題。

解析度

  1. 如果是自訂後端伺服器,請執行下列操作:
    1. 瞭解後端伺服器的回應時間過長,看看是否可修正/最佳化以加快回應速度。
    2. 如果您無法修正/最佳化後端伺服器,或已知後端伺服器花費很長的時間,請提高路由器和訊息處理器上的逾時值

      構想:依照下列順序設定不同元件的逾時值:

      用戶端逾時 > 路由器上的逾時 > 訊息處理器逾時 > API Proxy 中逾時

  2. 如果是 NodeJS 後端伺服器,請執行下列操作:
    1. 檢查 NodeJS 程式碼是否會呼叫任何其他後端伺服器,以及是否花費很長的時間才能傳回回應。瞭解後端伺服器花費較長時間的原因,並視情況修正問題。
    2. 檢查訊息處理器的 CPU 或記憶體用量是否偏高:
      1. 如果任何訊息處理器的 CPU 用量偏高,請使用下列指令每 30 秒產生三個執行緒傾印
        JAVA_HOME/bin/jstack -l PID > FILENAME
      2. 如果任何訊息處理器的記憶體用量偏高,請使用下列指令產生記憶體快照資料
        sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
      3. 使用下列指令重新啟動訊息處理器。應該會減少 CPU 和記憶體:
        /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
      4. 監控 API 呼叫,確認問題是否仍然存在。
      5. Apigee Edge 支援團隊聯絡,並提供執行緒傾印、記憶體快照資料和訊息處理器記錄檔 (/opt/apigee/var/log/edge-message-processor/logs/system.log),協助您調查 CPU/記憶體用量偏高的原因。

檢查此項目:如何控管訊息處理器上的 NodeJS 後端伺服器逾時

  • NodeJS 後端伺服器會在訊息處理器的 JVM 程序中執行。NodeJS 後端伺服器的逾時值是透過 nodejs.properties 檔案中的 http.request.timeout.seconds 屬性控制。根據預設,此屬性會設為 0,也就是說,如果這個訊息處理器提供的機構,所有 API Proxy 都會預設停用逾時設定。因此,即使 NodeJS 後端伺服器執行時間過長,訊息處理器也不會逾時。
  • 不過,如果 NodeJS 後端伺服器需要較長時間,且 API 要求耗用的時間超過 57 秒,路由器就會逾時,並將 504 Gateway Timeout 錯誤傳送至用戶端。

情境 #3:用戶端應用程式會在路由器/訊息處理器/後端伺服器回應之前逾時

如果用戶端應用程式在後端伺服器回應前逾時,就可能收到 504 Gateway Timeout 錯誤。發生這種情況的可能原因如下:

  1. 在用戶端應用程式設定的逾時值低於路由器和訊息處理器中設定的逾時值:

    舉例來說,如果設定了下列逾時值:

    用戶端逾時 路由器逾時 訊息處理器發生逾時
    50 秒 57 秒 55 秒

    在此情況下,透過 Edge 取得 API 要求回應所需的總時間 <= 50 秒。其中包括發出 API 要求所需的時間、邊緣 (Router、訊息處理器) 處理的要求、傳送至後端伺服器的要求 (如適用)、後端處理要求及傳送回應、Edge 處理回應,最後將回應傳回用戶端。

    如果路由器未在 50 秒內回應用戶端,用戶端將會逾時並關閉與路由器的連線。用戶端會取得 504 的回應代碼。

    這會導致 NGINX 設定狀態碼 499,表示用戶端已關閉連線。

診斷

  1. 如果用戶端應用程式在收到路由器的回應前逾時,就會關閉與路由器的連線。在這類情況下,特定 API 要求的 NGINX 存取記錄檔中會顯示狀態碼 499。

    顯示狀態碼 499 的 NGINX 記錄項目範例

  2. 在上述範例中,請注意,NGINX 的 499 狀態和經過總時間為 50.001 秒。這表示用戶端在 50.001 秒後逾時。
  3. 在此情況下,訊息處理器記錄檔 (/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>
    
    
    ) 中會顯示 Broken Pipe 個例外狀況
  4. 路由器逾時之後,就會關閉與訊息處理器的連線。訊息處理器完成處理作業後,會嘗試將回應寫入路由器。由於路由器的連線已關閉,您會在訊息處理器上取得 Broken Pipe exception
  5. 在上述情況中,這是正常的例外狀況。因此,發生 504 Gateway Timeout 錯誤的實際原因仍是後端伺服器的回應時間較長,且您必須解決該問題。

解析度

  1. 如果這是自訂後端伺服器,請採取以下動作:
    1. 查看後端伺服器,判斷為何處理時間超過 57 秒,看看這個伺服器是否能進行修正/最佳化來加快回應速度。
    2. 如果無法修正/最佳化後端伺服器,或是後端伺服器會花費很長的時間,請增加路由器和訊息處理器的逾時值

      構想:依照下列順序設定不同元件的逾時值:

      用戶端逾時 > 路由器上的逾時 > 訊息處理器逾時 > API Proxy 中逾時

  2. 如果是 NodeJS 後端,請執行下列操作:
    1. 檢查 NodeJS 程式碼是否會呼叫任何其他後端伺服器,以及這種狀況是否耗時過長。瞭解這些後端伺服器花費較長時間的原因。
    2. 檢查訊息處理器的 CPU 或記憶體用量是否偏高:
      1. 如果訊息處理器的 CPU 使用率偏高,請使用下列指令每 30 秒產生三個執行緒傾印
        JAVA_HOME/bin/jstack -l PID > FILENAME
      2. 如果訊息處理器的記憶體用量偏高,請使用下列指令產生記憶體快照資料
        sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
      3. 使用下列指令重新啟動訊息處理器。這應會減少 CPU 和記憶體:
        /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
      4. 監控 API 呼叫,確認問題是否仍然存在。
      5. Apigee Edge 支援團隊聯絡,並提供執行緒傾印、記憶體快照資料和訊息處理器記錄檔 (/opt/apigee/var/log/edge-message-processor/logs/system.log),幫助他們調查 CPU/記憶體用量偏高的原因。

增加路由器和訊息處理器的逾時值

根據您的需求,仔細選擇要在路由器和訊息處理器上設定的逾時值。請不要任意設定較大的逾時值。如需協助,請與 Apigee Edge 支援團隊聯絡。

路由器

chown apigee:apigee /opt/apigee/customer/application/router.properties
  1. 如果路由器上還沒有 /opt/apigee/customer/application/router.properties 檔案,請在路由器上建立檔案。
  2. 在這個檔案中新增下列程式碼:
    conf_load_balancing_load.balancing.driver.proxy.read.timeout=TIME_IN_SECONDS

    舉例來說,如果您想將逾時值設為 120 秒,請按照下列方式設定:

    conf_load_balancing_load.balancing.driver.proxy.read.timeout=120
  3. 請確保此檔案為 apigee 擁有:
  4. 重新啟動路由器:
    /opt/apigee/apigee-service/bin/apigee-service edge-router restart
    
  5. 如果你有多個路由器,請在所有路由器上重複上述步驟。

訊息處理器

  1. 如果訊息處理器機器上還沒有 /opt/apigee/customer/application/message-processor.properties 檔案,請在該機器上建立。
  2. 在這個檔案中新增下列程式碼:
    conf_http_HTTPTransport.io.timeout.millis=TIME_IN_MILLISECONDS

    舉例來說,如果您想將逾時值設為 120 秒,請按照下列方式設定:

    conf_http_HTTPTransport.io.timeout.millis=120000
  3. 確保這個檔案的擁有者為 Apigee:
    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
  4. 重新啟動訊息處理器:
    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
  5. 如果您擁有多個訊息處理器,請對所有訊息處理器重複上述步驟。

構想:請按照下列順序設定不同元件的逾時值:

用戶端逾時 > 路由器上的逾時 > 訊息處理器逾時 > API Proxy 中逾時

Edge 的 API 要求處理速度緩慢

如果 Edge 速度非常緩慢,且/或需要很長的時間處理 API 要求,您會收到 504 Gateway Timeout 錯誤。

診斷

  1. 在 Edge UI 中追蹤受影響的 API。
  2. 您可以等待錯誤發生,或是如果有 API 呼叫,然後發出一些 API 呼叫並重現 504 Gateway Timeout 錯誤。
  3. 請注意,在這種情況下,Trace 中可能會顯示成功的回應。
    1. 路由器/用戶端逾時,因為訊息處理器未在路由器/用戶端的指定逾時期限內 (以最短逾時期間為準) 做出回應。不過,訊息處理者會繼續處理要求,可能會順利完成。
    2. 此外,只有在訊息處理者與 HTTP/HTTPS 後端伺服器通訊時,訊息處理器上設定的 HTTPTransport.io.timeout.millis 值才會觸發。換句話說,如果 API Proxy 中的任何政策 (服務呼叫政策除外) 花費過長時間,就不會觸發逾時。
  4. 錯誤發生後,請檢查最長時間的特定要求。
  5. 檢查每個階段的經過時間,並記下花費最多時間的階段。
  6. 如果您在任何其他政策 (服務呼叫政策除外) 中觀察到最長時間,表示 Edge 處理要求所需的時間過長。
  7. 以下是顯示 JavaScript 政策經過時間過長的 UI 追蹤記錄範例:

  8. 在上述範例中,您會發現 JavaScript 政策花費的時間異常過長 (約 245 秒)。

解析度

  1. 檢查政策是否回應時間過長,以及是否有任何自訂程式碼可能需要較長的處理時間。如有任何這類程式碼,請看看能否修正/最佳化已識別的程式碼。
  2. 如果沒有可能會產生大量處理時間的自訂程式碼,請檢查訊息處理器是否耗用大量 CPU 或記憶體:
    1. 如果任何訊息處理器的 CPU 用量偏高,請使用下列指令每 30 秒產生三個執行緒傾印
      JAVA_HOME/bin/jstack -l PID > FILENAME
    2. 如果任何訊息處理器的記憶體用量偏高,請使用下列指令產生記憶體快照資料
      sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
    3. 使用下列指令重新啟動訊息處理器。這應會減少 CPU 和記憶體。
      /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    4. 監控 API 呼叫,確認問題是否仍然存在。
    5. Apigee Edge 支援團隊聯絡,並提供執行緒傾印、記憶體快照資料和訊息處理器記錄檔 (/opt/apigee/var/log/edge-message-processor/logs/system.log),幫助他們調查 CPU/記憶體用量偏高的原因。

使用 API 監控功能診斷問題

API 監控功能可讓您快速隔離問題區域,以診斷錯誤、效能與延遲問題及其來源 (例如開發人員應用程式、API Proxy、後端目標或 API 平台)。

逐步操作範例情境,示範如何使用 API Monitoring 排解 API 的 5xx 問題。舉例來說,您可以設定快訊,讓系統在 504 狀態碼數量超過特定門檻時收到通知。