502 网关无效 - TooBigBody

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

问题

客户端应用收到 HTTP 状态代码 502 Bad Gateway 和错误代码 protocol.http.TooBigBody ,以此响应 API 调用。

出错提示

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

HTTP/1.1 502 Bad Gateway

此外,您可能会看到以下错误消息:

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

可能的原因

如果目标/后端服务器作为 HTTP 响应的一部分发送到 Apigee Edge 的载荷大小大于 Apigee Edge 中允许的限制,则会发生此错误。

以下是此错误的可能原因:

原因 说明 适用的问题排查说明
响应载荷大小超出允许的限制 目标/后端服务器作为 HTTP 响应的一部分发送到 Apigee 的载荷大小大于 Apigee 中允许的限制。 Edge Public 和 Private Cloud 用户
解压缩后,响应载荷大小超出允许的限制 目标/后端服务器作为 HTTP 响应的一部分以压缩格式发送到 Apigee 的载荷大小在被 Apigee 解压缩后超过了允许的限制。 Edge Public 和 Private Cloud 用户

常见诊断步骤

您可以使用以下工具/方法来诊断此错误:

API 监控

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

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

  3. 前往分析 > API 监控 > 调查页面。
  4. 选择您发现错误的具体时间范围。
  5. 您可以选择代理过滤条件来缩小故障代码的范围。
  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 中允许的限制。

跟踪记录

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

  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. 您会在发送给客户端的响应阶段看到失败情况,如下所示:

  6. 记下轨迹中的误差值。上面的示例跟踪记录显示:
    • 错误: 502 Bad Gateway
    • 错误内容: {"fault":{"faultstring":"Body buffer overflow","detail":{"errorcode":"protocol.http.TooBigBody"}}}
  7. 根据不同场景,导航到从目标服务器收到的响应阶段,如下所示:

    未压缩

    场景 1:以未压缩形式发送的响应载荷

    记下轨迹中的错误值:

    • 从目标服务器收到的响应:200 OK
    • Content-Length(来自响应标头部分):约 11MB

    已压缩

    情形 2:以压缩形式发送的请求载荷

    记下轨迹中的错误值:

    • 从目标服务器收到的响应:200 OK
    • Content-Encoding:如果您在响应标头部分看到此标头,请记下相应的值。例如,在此示例中,该值为 gzip。
  8. 请注意响应内容部分下的正文:

    {"fault":{"faultstring":"Body buffer overflow","detail":{"errorcode":"protocol.http.TooBigBody"}}}
    
  9. 在轨迹中找到 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. 下表根据 target.received.content.length 的值,说明了在两种情形下 Apigee 返回 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 监控、Trace 工具或 NGINX 访问日志(如常见诊断步骤中的方案 1 所述)确定所观测到的错误的故障代码、故障来源和响应载荷大小。
  2. 如果“故障源”的值为 target,则表示目标/后端服务器发送给 Apigee 的响应载荷大小大于 Apigee Edge 中允许的限制。
  3. 验证根据第 1 步确定的响应载荷大小。
  4. 通过以下步骤检查实际响应,验证响应载荷大小是否确实超过了 10 MB 的允许限值:
    1. 如果您无法访问向目标/后端服务器发出的实际请求,请前往问题解决。
    2. 如果您有权访问向目标/后端服务器发出的实际请求,请执行以下步骤:
      1. 如果您是公有云/私有云用户,请直接从后端服务器本身或您获准向后端服务器发出请求的任何其他机器向后端服务器发出请求。
      2. 如果您是 Private Cloud 用户,也可以从某个消息处理器向后端服务器发出请求。
      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 监控、Trace 工具或 NGINX 访问日志(如常见诊断步骤中的方案 2 所述)确定所观测到的错误的故障代码、故障来源和响应载荷大小。
  2. 如果 Fault Source 的值为 target,则表示目标/后端应用发送给 Apigee 的响应载荷大小大于 Apigee Edge 中允许的限制。
  3. 验证根据第 1 步确定的响应载荷大小。
    • 如果载荷大小超过允许的 10 MB 限额,则会导致错误。
    • 如果载荷大小接近 10 MB 的允许上限,则响应载荷可能会以压缩格式传递。在这种情况下,请检查压缩响应载荷的未压缩大小。
  4. 您可以使用以下方法之一验证目标/后端发送的响应是否为压缩格式,以及未压缩的大小是否超过允许的限制:

    跟踪记录

    使用 Trace 工具:

    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:签名网址生成器示例所示。

流式

方法 3:使用流式传输

如果您的 API 代理需要处理非常大的请求和/或响应,您可以在 Apigee 中启用流式处理。

CwC

选项 4:使用 CwC 属性来提高缓冲区限制

仅当您无法使用任何推荐的选项时,才应使用此选项,因为如果增加默认大小,可能会出现性能问题。

Apigee 提供了一个 CwC 属性,可用于提高请求和响应载荷大小限制。如需了解详情,请参阅 在路由器或消息处理器上设置消息大小限制。

限制

Apigee 希望客户端应用和后端服务器不要发送大于 Apigee Edge 限制中针对 Request/response size 记录的允许限制的载荷大小。

  1. 如果您是公共云用户,则请求和响应载荷大小的上限与 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 代理名称
  • 用于重现 502 错误的完整 curl 命令
  • API 请求的轨迹文件
  • 来自目标/后端服务器的响应的完整输出,以及载荷的大小

如果您是私有云用户,请提供以下信息:

  • 失败请求的完整错误消息
  • 组织名称
  • 环境名称
  • API 代理软件包
  • 失败的 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