502 閘道錯誤 - TooBigBody

您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件。
info

問題

用戶端應用程式會收到 HTTP 狀態碼 502 Bad Gateway,以及錯誤碼 protocol.http.TooBigBody ,做為 API 呼叫的回應。

錯誤訊息

用戶端應用程式會取得下列回應代碼:

HTTP/1.1 502 Bad Gateway

此外,您可能會看到下列錯誤訊息:

{
   "fault":{
      "faultstring":"Body buffer overflow",
      "detail":{
         "errorcode":"protocol.http.TooBigBody"
      }
   }
}

可能原因

如果目標/後端伺服器傳送至 Apigee Edge 的 HTTP 回應酬載大小,超過 Apigee Edge 允許的上限,就會發生這個錯誤。

以下是可能導致錯誤的原因:

原因 說明 適用於以下裝置的疑難排解說明
回應酬載大小超過允許的上限 目標/後端伺服器傳送的酬載大小 (HTTP 回應的一部分) 超過 Apigee 允許的上限。 Edge 公有和私有雲使用者
解壓縮後,回應酬載大小超過允許的上限 目標/後端伺服器以壓縮格式傳送的酬載大小,在 Apigee 解壓縮後超過允許的上限 (這是 HTTP 回應的一部分)。 Edge 公有和私有雲使用者

常見的診斷步驟

請使用下列其中一種工具/技術診斷這項錯誤:

API Monitoring

如要使用 API 監控功能診斷錯誤,請按照下列步驟操作:

  1. 以具備 適當角色的使用者身分登入 Apigee Edge UI。
  2. 切換至要調查問題的機構。

  3. 依序前往「Analyze」>「API Monitoring」>「Investigate」頁面。
  4. 選取您觀察到錯誤的特定時間範圍。
  5. 您可以選取「Proxy」篩選器,縮小故障代碼範圍。
  6. 繪製「錯誤代碼」與「時間」的關係圖。
  7. 選取含有故障代碼 protocol.http.TooBigBody 的儲存格,如下所示:

  8. 畫面上會顯示故障代碼 protocol.http.TooBigBody 的相關資訊,如下所示:

  9. 按一下「查看記錄」,然後展開失敗要求所在的資料列。

  10. 在「記錄」視窗中,記下下列詳細資料:
    • 狀態碼: 502
    • 錯誤來源: target
    • 故障代碼: protocol.http.TooBigBody。
  11. 如果「Fault Source」的值為 target,且「Fault Code」的值為 protocol.http.TooBigBody,表示目標/ 後端伺服器的 HTTP 回應酬載大小超過 Apigee Edge 允許的限制。

追蹤記錄

如要使用「追蹤」工具診斷錯誤,請按照下列步驟操作:

  1. 啟用追蹤工作階段,並執行下列任一操作:
    • 等待發生 502 Bad Gateway 錯誤,或
    • 如果可以重現問題,請發出 API 呼叫並重現 502 Bad Gateway 錯誤。
  2. 選取其中一個失敗的要求,然後檢查追蹤記錄。
  3. 瀏覽追蹤記錄的不同階段,找出發生失敗的位置。
  4. 如下所示,前往「Response received from target server」(從目標伺服器收到回應) 階段之後的「Error」(錯誤) 階段:

    請注意追蹤記錄中的錯誤值:

    • 錯誤: Body buffer overflow
    • error.class:com.apigee.errors.http.server.BadGateway

    這表示 Apigee Edge (訊息處理器元件) 收到後端伺服器的回應時,會立即擲回錯誤,因為酬載大小超過允許的上限。

  5. 如下所示,您會在「Response Sent to Client」階段看到失敗訊息:

  6. 請記下追蹤記錄中的錯誤值。上述追蹤記錄樣本顯示:
    • 錯誤: 502 Bad Gateway
    • 錯誤內容: {"fault":{"faultstring":"Body buffer overflow","detail":{"errorcode":"protocol.http.TooBigBody"}}}
  7. 根據不同情境,前往「Response Received from target server」(從目標伺服器收到回應) 階段,如下所示:

    未壓縮

    情境 #1:以未壓縮形式傳送的回應酬載

    請注意追蹤記錄中的錯誤值:

    • 收到目標伺服器的回應:200 OK
    • Content-Length (來自「Response Headers」部分):約 11 MB

    經過壓縮

    情境 2:以壓縮形式傳送要求酬載

    請注意追蹤記錄中的錯誤值:

    • 收到目標伺服器的回應:200 OK
    • Content-Encoding:如果「Response Headers」 部分顯示這個標頭,請記下該值。舉例來說,在本範例中,這個值為 gzip。
  8. 請注意「Response Content」(回應內容) 區段下方的「Body」:

    {"fault":{"faultstring":"Body buffer overflow","detail":{"errorcode":"protocol.http.TooBigBody"}}}
    
  9. 前往追蹤記錄中的「AX」(記錄的 Analytics 資料) 階段,然後點選該階段,即可查看相關詳細資料。AX

  10. 在「階段詳細資料」中向下捲動至「讀取的變數」部分,然後判斷 target.received.content.length 的值,這表示:
    • 以未壓縮格式傳送時,回應酬載的實際大小
    • 酬載以壓縮格式傳送時,Apigee 解壓縮後的回應酬載大小。在此情境中,這個值一律會與允許的上限值 (10 MB) 相同。

    未壓縮

    情境 #1:以未壓縮形式傳送的回應酬載

    請注意 target.received.content.length 的值:

    要求標頭 值
    target.received.content.length 約 11 MB

    經過壓縮

    情境 2:以壓縮形式傳送要求酬載

    請注意 target.received.content.length 的值:

    要求標頭 值
    target.received.content.length 約 10 MB
  11. 下表說明在兩種情境下,Apigee 為何會根據 target.received.content.length 的值傳回 502 錯誤:

    情境 target.received.content.length 的值 失敗原因
    未壓縮格式的回應酬載 約 11 MB 大小超過上限 (10 MB)
    壓縮格式的回應酬載 約 10 MB

    解壓縮後超過大小上限

NGINX

如要使用 NGINX 存取記錄診斷錯誤,請按照下列步驟操作:

  1. 如果您是私有雲使用者,可以透過 NGINX 存取記錄判斷 HTTP 502 錯誤的關鍵資訊。
  2. 檢查 NGINX 存取記錄:

    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    說明: ORG、ENV 和 PORT# 會替換為實際值。

  3. 搜尋特定時間範圍內是否有任何502錯誤 (如果問題發生在過去),或是否有任何要求仍會失敗並顯示 502。
  4. 如果發現任何 502 錯誤,且 X-Apigee-fault-code 與 protocol.http.TooBigBody 的值相符,請判斷 X-Apigee-fault-source 的值。

    NGINX 存取記錄檔中的 502 錯誤範例:

    上述 NGINX 存取記錄檔的範例項目,X-Apigee-fault-code 和 X-Apigee-fault-source 的值如下:

    回應標頭 值
    X-Apigee-fault-code protocol.http.TooBigBody
    X-Apigee-fault-source target

原因:回應酬載大小超過允許的上限

診斷

  1. 使用 API 監控、追蹤工具或 NGINX 存取記錄,判斷所觀察到的錯誤的錯誤代碼、錯誤來源和回應酬載大小,如常見診斷步驟中的情境 1 所述。
  2. 如果「Fault Source」的值為 target,表示目標/後端伺服器傳送至 Apigee 的回應酬載大小,大於 Apigee Edge 允許的限制。
  3. 驗證回應酬載大小,如步驟 1 所判斷。
    • 如果酬載大小超過 10 MB 的上限,就會導致錯誤。
    • 如果酬載大小接近 10 MB 的上限,回應酬載可能以壓縮格式傳遞。前往「原因:解壓縮後,回應酬載大小超過允許的上限」。
  4. 請按照下列步驟檢查實際的回應,確認回應酬載大小確實超過 10 MB 的上限:
    1. 如果無法存取向目標/後端伺服器發出的實際要求,請前往「解決方法」。
    2. 如果您可以存取傳送至目標/後端伺服器的實際要求,請執行下列步驟:
      1. 如果您是公有雲/私有雲使用者,請直接從後端伺服器本身,或任何允許您向後端伺服器提出要求的機器,向後端伺服器提出要求。
      2. 如果您是私有雲使用者,也可以從其中一個訊息處理器向後端伺服器提出要求。
      3. 檢查「Content-Length」標頭,確認回應中傳遞的酬載大小。
      4. 如果發現酬載大小超過 Apigee Edge 允許的上限,這就是問題的原因。

    後端伺服器的範例回應:

    curl -v https://BACKENDSERVER-HOSTNAME/testfile
    
    * About to connect() to 10.14.0.10 port 9000 (#0)
    *   Trying 10.14.0.10...
    * Connected to 10.14.0.10 (10.148.0.10) port 9000 (#0)
    > GET /testfile HTTP/1.1
    > User-Agent: curl/7.29.0
    > Host: 10.14.0.10:9000
    > Accept: */*
    >
    < HTTP/1.1 200 OK
    < Accept-Ranges: bytes
    < Content-Length: 11534336
    < Content-Type: application/octet-stream
    < Last-Modified: Wed, 30 Jun 2021 08:18:02 GMT
    < Date: Wed, 30 Jun 2021 09:22:41 GMT
    <
    ----snipped----
    <Response Body>

    在上述範例中,您可以看到 Content-Length: 11534336 (which is ~11 MB) 是造成這項錯誤的原因,因為它超過了 Apigee Edge 允許的限制。

解析度

請參閱「解決方法」。

原因:解壓縮後,回應酬載大小超過允許的上限

如果回應酬載是以壓縮格式傳送,且回應標頭 Content-Encoding 設為 gzip, ,Apigee 會解壓縮回應酬載。在解壓縮過程中,如果 Apigee 發現酬載大小大於 Apigee Edge 中允許的限制,就會停止進一步解壓縮,並立即以 502 Bad Gateway 和錯誤代碼 protocol.http.TooBigBody 回應。

診斷

  1. 使用 API 監控、追蹤工具或 NGINX 存取記錄,判斷觀察到的錯誤的錯誤代碼、錯誤來源和回應酬載大小,如常見診斷步驟的案例 2 所述。
  2. 如果「Fault Source」(錯誤來源) 的值為 target,表示目標/後端應用程式傳送至 Apigee 的回應酬載大小,大於 Apigee Edge 中 允許的限制。
  3. 驗證回應酬載大小,如步驟 1 所判斷。
    • 如果酬載大小超過 10 MB 的上限,就是造成錯誤的原因。
    • 如果酬載大小接近 10 MB 的允許上限,則回應酬載可能會以壓縮格式傳遞。在這種情況下,請檢查壓縮後的回應酬載未壓縮大小。
  4. 如要驗證目標/後端傳送的回應是否為壓縮格式,且未壓縮的大小是否超出允許的限制,請使用下列其中一種方法:

    追蹤記錄

    使用「追蹤」工具:

    1. 如果您已擷取失敗要求的追蹤記錄,請參閱「追蹤記錄」和「
      1. 判斷 target.received.content.length 的值
      2. 確認用戶端的要求是否包含 Content-Encoding: gzip 標頭
    2. 如果 target.received.content.length 的值接近 10 MB 的允許上限,且回應標頭為 Content-Encoding: gzip,則這就是導致錯誤的原因。

    實際要求

    使用實際要求:

    1. 如果無法存取向目標/後端伺服器發出的實際要求,請前往「解決方法」。
    2. 如果您可以存取傳送至目標/後端伺服器的實際要求,請執行下列步驟:
      1. 驗證回應中傳遞的酬載大小,以及回應中傳送的 Content-Encoding 標頭。
      2. 如果發現回應標頭 Content-Encoding 設為 gzip,且酬載的未壓縮大小超過 Apigee Edge 允許的上限,就是導致這項錯誤的原因。

        從後端伺服器收到的範例回應:

        curl -v https://BACKENDSERVER-HOSTNAME/testzippedfile.gz
        
        * About to connect() to 10.1.0.10 port 9000 (#0)
        *   Trying 10.1.0.10...
        * Connected to 10.1.0.10 (10.1.0.10) port 9000 (#0)
        > GET /testzippedfile.gz HTTP/1.1
        > User-Agent: curl/7.29.0
        > Host: 10.1.0.10:9000
        > Accept: */*
        >
        < HTTP/1.1 200 OK
        < Accept-Ranges: bytes
        < Content-Encoding: gzip
        < Content-Type: application/x-gzip
        < Last-Modified: Wed, 30 Jun 2021 08:18:02 GMT
        < Testheader: test
        < Date: Wed, 07 Jul 2021 10:14:16 GMT
        < Transfer-Encoding: chunked
        <
        ----snipped----
        <Response Body>

        在上述情況中,系統會傳送標頭 Content-Encoding: gzip,且回應中檔案 testzippedfile.gz 的大小小於上限,但未壓縮檔案 testzippedfile 的大小約為 15 MB。

    訊息處理器記錄

    使用訊息處理器記錄:

    1. 如果您是私有雲使用者,則可使用訊息處理器記錄,判斷 HTTP 502 錯誤的關鍵資訊。
    2. 檢查訊息處理器記錄

      /opt/apigee/var/log/edge-message-processor/logs/system.log

    3. 搜尋特定時間範圍內是否有任何502錯誤 (如果問題發生在過去),或是否有任何要求仍502失敗。您可以使用下列搜尋字串:

      grep -ri "chunkCount"
      
      grep -ri "BadGateway: Body buffer overflow"
      
    4. 您會看到類似下方的 system.log 行 (您的 TotalRead 和 chunkCount 可能有所不同):
      2021-07-07 09:40:47,012  NIOThread@7 ERROR HTTP.SERVICE -
      TrackingInputChannel.checkMessageBodyTooLarge() : Message is too large.
      TotalRead 10489856 chunkCount 2571
      
      2021-07-07 09:40:47,012  NIOThread@7 ERROR HTTP.CLIENT -
      HTTPClient$Context.onInputException() :
      ClientInputChannel(ClientChannel[Connected:
      Remote:10.148.0.10:9000 Local:10.148.0.9:42240]@9155
      useCount=1 bytesRead=0 bytesWritten=182 age=23ms  lastIO=0ms
      isOpen=true).onExceptionRead exception: {}
      com.apigee.errors.http.server.BadGateway: Body buffer overflow
      
      2021-07-07 09:40:47,012  NIOThread@7 ERROR
      ADAPTORS.HTTP.FLOW - AbstractResponseListener.onException() :
      AbstractResponseListener.onError(HTTPResponse@77cbd7c4,
      Body buffer overflow)
    5. 在解壓縮過程中,只要訊息處理器判斷讀取的位元組總數 > 10 MB,就會停止並輸出以下行:

      Message is too large. TotalRead 10489856 chunkCount 2571

      這表示「回應酬載大小」超過 10 MB,且當大小開始超過 10 MB 的限制時,Apigee 會擲回錯誤,錯誤代碼為 protocol.http.TooBigBody。

解析度

修正大小

選項 1 (建議):修正目標伺服器應用程式,避免傳送超過 Apigee 限制的酬載大小

  1. 分析特定目標伺服器傳送的回應 / 酬載大小超出 限制的原因。
  2. 如果不希望這樣,請修改目標伺服器應用程式,讓其傳送的回應 / 酬載大小低於允許的上限。
  3. 如果需要傳送超過限制的回覆/酬載,請參閱下一個選項。

經簽署的網址模式

選項 2 (建議):在 Apigee JavaCallout 中使用已簽署的網址模式

如果酬載大小超過 10 MB,Apigee 建議在 Apigee JavaCallout 中使用經簽署的網址模式,如 GitHub 上的 Edge Callout: Signed URL Generator 範例所示。

串流

選項 3:使用串流

如果 API Proxy 需要處理非常大的要求和/或回應,您可以在 Apigee 中啟用串流。

CwC

選項 4:使用 CwC 屬性提高緩衝區限制

只有在無法使用任何建議選項時,才應使用這個選項,因為如果增加預設大小,可能會導致效能問題。

Apigee 提供 CwC 屬性,可提高要求和回應酬載大小 上限。詳情請參閱 在路由器或訊息處理器上設定訊息大小限制。

限制

Apigee 預期用戶端應用程式和後端伺服器不會傳送超過允許上限的酬載大小,如 Apigee Edge 限制中 Request/response size 的文件所述。

  1. 如果您是 Public Cloud 使用者,要求和回應酬載大小上限如 Apigee Edge 限制所述,適用於 Request/response size。
  2. 如果您是私有雲使用者 ,可能已修改要求和回應酬載大小的預設上限 (即使不建議這麼做)。如要判斷要求酬載大小上限,請按照「如何查看目前上限」一文中的操作說明進行。

如何查看目前的限制?

本節說明如何確認屬性 HTTPResponse.body.buffer.limit 已在訊息處理器上更新為新值。

  1. 在訊息處理器電腦上,搜尋 /opt/apigee/edge-message- processor/conf 目錄中的 HTTPResponse.body.buffer.limit 屬性,然後檢查已設定的值,如下所示:

    grep -ri "HTTPResponse.body.buffer.limit" /opt/apigee/edge-message-processor/conf
    
  2. 上述指令的範例結果如下:

    /opt/apigee/edge-message-processor/conf/http.properties:HTTPResponse.body.buffer.limit=10m
  3. 在上述範例輸出內容中,請注意屬性 HTTPResponse.body.buffer.limit 已在 http.properties 中設為值 10m。

    這表示在 Apigee for Private Cloud 中,要求酬載大小的上限為 10 MB。

如果仍需要 Apigee 支援團隊協助,請參閱「 必須收集診斷資訊」。

必須收集診斷資訊

收集下列診斷資訊,然後聯絡 Apigee Edge 支援團隊:

如果您是公有雲使用者,請提供下列資訊:

  • 機構名稱
  • 環境名稱
  • API Proxy 名稱
  • 用於重現 502 錯誤的完整 curl 指令
  • API 要求的追蹤記錄檔
  • 目標/後端伺服器的完整回應輸出內容,以及酬載大小

如果您是 Private Cloud 使用者,請提供下列資訊:

  • 失敗要求顯示的完整錯誤訊息
  • 機構名稱
  • 環境名稱
  • API Proxy 套裝組合
  • 失敗 API 要求的追蹤記錄檔
  • 用於重現 502 錯誤的完整 curl 指令
  • 目標/後端伺服器的完整回應輸出內容,以及酬載大小
  • NGINX 存取記錄 /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    說明: ORG、ENV 和 PORT# 會替換為實際值。

  • 訊息處理器系統記錄 /opt/apigee/var/log/edge-message-processor/logs/system.log