502 网关无效 - 解压缩失败响应

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档。
info

问题

客户端应用收到 HTTP 状态代码 502 Bad Gateway,错误代码为 messaging.adaptors.http.flow.DecompressionFailureAtResponse,以此响应 API 调用。

出错提示

客户端应用获取以下响应代码:

HTTP/1.1 502 Bad Gateway

此外,您可能会看到类似于以下内容的错误消息:

{
   "fault":{
      "faultstring":"Decompression failure at response",
      "detail":{
         "errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtResponse"
      }
   }
}

可能的原因

仅在以下情况下,会发生此错误:

  • 在后端/目标服务器的 HTTP 响应 标头 Content-Encoding 中指定的编码有效且 受 Apigee Edge 支持。
  • 但是

  • 后端/目标服务器作为 HTTP 响应 的一部分发送的载荷格式与 Content-Encoding 标头中指定的编码格式不匹配。

这是因为 Apigee Edge 无法使用指定的编码对载荷进行解码,因为载荷的格式与 Content-Encoding 标头中指定的编码格式不一致。

以下是一些受支持的 Content-Encoding 值示例,以及 Apigee Edge 在这些情况下期望的载荷表示形式:

场景 Content-Encoding 载荷表示形式
单编码 gzip

Unix gzip 格式。

请参阅 RFC1952 GZIP 格式。

单编码 deflate

此格式使用 zlib 结构和 deflate 压缩算法。

请参阅 RFC1950 和 RFC1951.

多编码

多编码

例如,如果编码执行两次,则可以是:

  • gzip、deflate
  • gzip、gzip
  • deflate、gzip
  • deflate、deflate
按照标头中显示的顺序对载荷应用多编码。

造成此错误的可能原因如下:

原因 说明 适用的问题排查说明
响应载荷格式与 Content-Encoding 不匹配 后端/目标服务器发送的响应载荷的格式未编码,或者与 Content-Encoding 标头中指定的编码不匹配。 Edge Public 和 Private Cloud 用户

常见诊断步骤

请使用以下工具/技术之一来诊断此错误:

API 监控

如需使用 API 监控诊断错误,请执行以下操作:

  1. 以具有 适当角色的用户身份登录 Apigee Edge 界面。
  2. 切换到您要调查问题的组织。

  3. 依次前往 Analyze > API Monitoring > Investigate 页面。
  4. 选择您观察到错误的具体时间范围。
  5. 确保 Proxy 过滤条件设置为 All 。
  6. 绘制 Fault Code 与 Time 的关系图。
  7. 选择一个单元格,其中包含故障代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse,如下所示:

    ( 查看放大图片)

  8. 系统会显示有关故障代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse 的信息,如下所示:

    ( 查看放大图片)

  9. 点击 View logs ,然后展开因 502 错误而失败的行。

    ( 查看放大图片)

  10. 在 Logs 窗口中,记下以下详细信息:
    • 状态代码: 502
    • 故障来源: target
    • 故障代码: messaging.adaptors.http.flow.DecompressionFailureAtResponse。
  11. 如果 Fault Source 的值为 target,则表示响应载荷格式与后端服务器的响应标头 Content-Encoding 中指定的 受支持编码 不匹配。

跟踪工具

如需使用跟踪工具诊断错误,请执行以下操作:

  1. 启用跟踪会话 然后执行以下任一操作:
    1. 等待 502 Bad Gateway 错误发生,或
    2. 如果您可以重现此问题,请进行 API 调用并重现 502 Bad Gateway。
  2. 确保启用显示所有 FlowInfo :

  3. 选择一个失败的响应,然后检查跟踪记录。
  4. 浏览跟踪记录的不同阶段,找到发生失败的位置 。
  5. 您通常会在 从目标服务器收到的响应 阶段之后的流中找到错误,如下所示:

    ( 查看放大图片)

  6. 记下跟踪记录中的属性值:

    • Content-Encoding: gzip
    • 响应内容正文: {"fault":{"faultstring":"Decompression failure at response","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtResponse"}}}
  7. 前往从目标服务器收到的响应 阶段之后的错误阶段:

    ( 查看放大图片)

    记下属性:

    • 错误: Decompression failure at response
    • error.class:: com.apigee.errors.http.server.BadGateway
    • error.cause:: Not in GZIP format

      error.cause 表明响应载荷不是 GZIP 格式。 这意味着 Apigee Edge 期望响应载荷采用 GZIP 格式,如 在 Content-Encoding 标头中所指定(在上一步中确定)。因此,Apigee Edge 无法使用 gzip 对载荷进行解压缩,并返回 错误 Decompression failure at response。

    请注意,在这种情况下,来自目标/后端服务器的响应为 200;但是,由于错误是由 Apigee Edge 返回的,因此客户端应用将收到 502 响应。

  8. 前往跟踪记录中的发送给客户端的响应 阶段,然后点击该阶段。

    ( 查看放大图片)

    记下跟踪记录中的以下详细信息:

    • 状态代码: 502 Bad Gateway。
    • 错误内容: {"fault":{"faultstring":"Decompression failure at response","detail":{"errorcode":"messaging.adaptors.http.flow.DecompressionFailureAtResponse"}}}
  9. 前往跟踪记录中的 AX (记录的分析数据)阶段 然后点击该阶段。

  10. 向下滚动到 Phase Details(阶段详细信息)、Error Headers(错误标头)部分,然后确定 X-Apigee-fault-code 和 X-Apigee-fault-source 的值,如下所示:

    ( 查看放大图片)

  11. 您将看到 X-Apigee-fault-code 和 X-Apigee-fault-source 的值分别为 messaging.adaptors.http.flow.DecompressionFailureAtResponse 和 target,这表示响应载荷格式与 Content-Encoding 标头中指定的编码不匹配。
    响应标头 值
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtResponse
    X-Apigee-fault-source target

NGINX

如需使用 NGINX 访问日志诊断错误,请执行以下操作:

  1. 如果您是 Private Cloud 用户 ,则可以使用 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 与 messaging.adaptors.http.flow.DecompressionFailureAtResponse 的值匹配,请确定 X-Apigee-fault-source 的值。

    NGINX 访问日志中的 502 错误示例:

    NGINX 访问日志中的上述示例条目具有以下 X-Apigee-fault-code 和 X-Apigee-fault-source:值:

    响应标头 值
    X-Apigee-fault-code messaging.adaptors.http.flow.DecompressionFailureAtResponse
    X-Apigee-fault-source target

原因:响应载荷格式与 Content-Encoding 不匹配

默认情况下,如果响应标头 Content-Encoding包含有效且 受支持的编码,Apigee Edge 始终会对载荷进行解压缩。因此,响应载荷的格式 应与 响应标头 Content-Encoding 中指定的编码匹配 。如果存在不匹配的情况,您会收到此错误。

诊断

  1. 使用 API 监控、跟踪工具或 NGINX 访问日志确定观察到的错误的故障代码 和故障来源 ,如常见诊断步骤中所述。
  2. 如果故障代码为 messaging.adaptors.http.flow.DecompressionFailureAtResponse,且 故障来源的值为target,则表示后端/目标服务器发送的响应载荷的格式与 响应标头Content-Encoding中指定的 受支持编码不匹配。
  3. 您可以使用以下方法之一确定 HTTP 响应中的不匹配情况:

    出错提示

    如需使用错误消息进行验证,请执行以下操作:

    1. 如果您有权访问从 Apigee Edge 收到的完整错误消息,请参阅 faultstring。

      示例错误消息:

      "faultstring":"Decompression failure at response"
    2. 在上述错误消息中,它显示了 "Decompression failure at response",这意味着无法使用 Content-Encoding标头中指定的编码对响应 进行解压缩。

    跟踪记录

    如需使用跟踪记录进行验证,请执行以下操作:

    1. 使用 跟踪记录 确定 Content-Type 和 error.cause,如 常见诊断步骤 中所述。
    2. 示例跟踪记录中的值如下所示:

      • Content-Encoding: gzip
      • error.cause:: Not in GZIP format

      响应标头 Content-Encoding 中的值为 gzip; 但是,响应载荷不是 GZIP 格式 (如 error.cause所示)。因此,Apigee Edge 会返回 502 Bad Gateway 和错误代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse。

    实际请求

    如需使用实际请求进行验证,请执行以下操作:

    如果您有权访问向目标/后端服务器 应用发出的实际请求,请执行以下步骤:

    1. 如果您是 Public Cloud/Private Cloud 用户,请直接从后端服务器本身或您有权向后端服务器发出请求的任何其他机器向后端服务器发出请求。
    2. 如果您是 Private Cloud 用户,还可以从其中一个消息处理器向后端服务器发出请求 。
    3. 检查后端服务器发送的响应,并确定在响应标头 Content-Encoding. 中传递的值
    4. 确定作为请求的一部分发送的载荷的格式。
    5. 如果 Content-Encoding 标头的值位于 受支持的编码列表中,但响应载荷的格式与 Content-Encoding 标头中指定的编码不匹配,则这是导致问题的原因。

      示例:

      curl -v https://HOSTALIAS/test
      

      ***trimmed***
      >
      < HTTP/1.1 200 OK
      < Accept-Ranges: bytes
      < Content-Encoding: gzip
      < Date: Mon, 02 Aug 2021 08:17:35 GMT
      < Transfer-Encoding: chunked
      <
      < response_payload.zip Response Body(not in GZIP format)>
      

      上述示例响应将值 gzip 发送到 Content-Encoding 标头,这是 受支持的编码 在 Apigee Edge 中。但是, response_payload.zip 作为 zip 文件发送。因此,此 响应因 502 Bad Gateway 错误而失败,错误代码为 messaging.adaptors.http.flow.DecompressionFailureAtResponse。

    消息处理器日志

    如需使用消息处理器日志进行验证,请执行以下操作:

    如果您是 Private Cloud 用户,则可以使用消息处理器日志 来确定有关 HTTP 502 错误的关键信息。

    1. 查看消息处理器日志:

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

    2. 搜索以查看在特定 时间段内(如果问题发生在过去)是否存在任何 502 错误,或者是否仍有任何响应 因 502 而失败。您可以使用以下搜索字符串:

      grep -ri "ZipException"
      
    3. 您将找到类似于以下内容的 system.log 中的行:

      情景 #1

      情景 #1:当 API 响应具有标头 Content-Encoding: gzip 时

      2021-08-02 06:50:25,433  NIOThread@2 ERROR HTTP.CLIENT -
      HTTPClient$Context.onInputException() :  ClientInputChannel(ClientChannel[Connected:
      Remote:3.8.1.1:9000 Local:10.0.115.32:41298]@38140 useCount=1 bytesRead=0
      bytesWritten=203 age=469ms  lastIO=0ms  isOpen=true).onExceptionRead exception: {}
      java.util.zip.ZipException: Not in GZIP format
      ---trimmed--
      2021-08-02 06:50:25,433  NIOThread@2 INFO  HTTP.CLIENT -
      HTTPClient$Context.logContextDetails() : Request details : host=null
      path=/folder/testFile method=GET. Channel details : Bytes read=0
      2021-08-02 06:50:25,434  NIOThread@2 ERROR ADAPTORS.HTTP.FLOW -
      AbstractResponseListener.onException() : AbstractResponseListener.onError(HTTPResponse@4806fdab, Not in GZIP format)
      2021-08-02 06:50:25,434  NIOThread@2 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception
      java.util.zip.ZipException: Not in GZIP format
      occurred while writing to channel null
      2021-08-02 06:50:25,434  NIOThread@2 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception trace:
      java.util.zip.ZipException: Not in GZIP format
      

      上述错误消息中的行 java.util.zip.ZipException: Not in GZIP format 表示响应载荷不是以 GZIP 格式发送的,即使 Content-Encoding 指定为 gzip 也是如此。因此,Apigee Edge 会抛出异常,并向客户端应用返回 502 状态代码和故障代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse 。

      情景 #2

      情景 #2:当 API 响应具有标头 Content-Encoding: deflate 时

      2021-08-02 06:35:21,215  NIOThread@0 ERROR HTTP.CLIENT -
      HTTPClient$Context.onInputException() :  ClientInputChannel(ClientChannel[Connected:
      Remote:3.8.1.1:9000 Local:192.168.194.140:35224]@36014 useCount=1 bytesRead=0
      bytesWritten=202 age=439ms  lastIO=2ms  isOpen=true).onExceptionRead exception: {}
      java.util.zip.ZipException: incorrect header check
      ---trimmed----
      Caused by:
      java.util.zip.DataFormatException: incorrect header check
      ---trimmed---
      2021-08-02 06:35:21,215  NIOThread@0 INFO  HTTP.CLIENT -
      HTTPClient$Context.logContextDetails() : Request details :
      host=null path=/folder/testFile method=GET. Channel details : Bytes read=0
      2021-08-02 06:35:21,216  NIOThread@0 ERROR ADAPTORS.HTTP.FLOW -
      AbstractResponseListener.onException() : AbstractResponseListener.onError(HTTPResponse@3966e277,
      incorrect header check)
      2021-08-02 06:35:21,216  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception
      java.util.zip.ZipException: incorrect header check occurred while writing to channel null
      2021-08-02 06:35:21,217  NIOThread@0 INFO  HTTP.SERVICE -
      ExceptionHandler.handleException() : Exception trace:
      java.util.zip.ZipException: incorrect header check
      
      

      上述错误消息中的行 java.util.zip.ZipException: incorrect header check 和 Caused by: java.util.zip.DataFormatException: incorrect header check 表示响应载荷不是以 deflate 格式发送的,并且与 deflate 的 Content-Encoding 标头中指定的编码不匹配。因此,Apigee Edge 会抛出异常,并向客户端应用返回 502 状态代码和 故障代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse 。

分辨率

  1. 如果 Apigee Edge 和后端服务器中的 API 代理流不需要压缩的响应载荷,请不要 传递 Content-Encoding 标头。如果需要压缩响应载荷,请转到第 2 步。
  2. 如果需要压缩响应载荷,请确保后端服务器 始终发送以下内容:
    • 任何 受支持的编码作为 响应中 Content-Encoding 标头的值
    • Apigee Edge 中受支持格式的响应载荷与 Content-Encoding 标头中指定的编码 格式匹配
  3. 在上面讨论的示例中,响应载荷采用 ZIP 格式,但响应标头 指定 Content-Encoding: gzip。您可以通过将响应 标头发送为 Content-Encoding: gzip 并将响应载荷发送为 gzip 格式:
    curl -v https://HOSTALIAS/v1/test
    
    >
    < HTTP/1.1 200 OK
    < Accept-Ranges: bytes
    < Content-Encoding: gzip
    < Date: Mon, 02 Aug 2021 08:17:35 GMT
    < Transfer-Encoding: chunked
    <
    < response_payload.gz Response Body(in GZIP format)>
    

规范

Apigee Edge 会根据以下 RFC 规范 返回状态代码 502 Bad Gateway 和错误代码 messaging.adaptors.http.flow.DecompressionFailureAtResponse:

规范
RFC 7231 第 6.5.1 节
RFC 7231 第 3.1.2.2 节

如果您仍然需要 Apigee 支持团队的任何帮助,请参阅 必须收集诊断信息。

必须收集的诊断信息

收集以下诊断信息,然后与 Apigee Edge 支持团队联系:

如果您是 Public Cloud 用户,请提供以下信息:

  • 组织名称
  • 环境名称
  • API 代理名称
  • 用于重现 502 错误的完整 curl 命令
  • API 响应的跟踪文件

如果您是 Private Cloud 用户,请提供以下信息:

  • 针对失败的响应观察到的完整错误消息
  • 环境名称
  • API 代理软件包
  • API 响应的跟踪文件
  • 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