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 中允许的限制,就会发生此错误。

以下是可能导致该错误的原因:

原因 说明 适用的问题排查说明
响应载荷大小超出允许的上限 目标/后端服务器在向 Apigee 发出的 HTTP 响应中发送的载荷大小超出 Apigee 中允许的上限。 Edge 公有云和私有云用户
解压缩后的响应载荷大小超出允许的上限 目标/后端服务器在向 Apigee 发出的 HTTP 响应中以压缩格式发送的载荷大小超出 Apigee 解压缩后允许的上限。 Edge 公有云和私有云用户

常见诊断步骤

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

API 监控

要使用 API Monitoring 诊断错误,请执行以下操作:

  1. 以拥有 适当角色的用户身份 登录 Apigee Edge 界面
  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. 如果故障来源的值为 target故障代码的值为 protocol.http.TooBigBody,则表示来自目标/ 后端服务器的 HTTP 响应的响应载荷大小大于 Apigee Edge 中允许的限制

跟踪记录

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

  1. 启用跟踪会话,并执行以下任一操作:
    • 等待 502 Bad Gateway 错误发生,或者
    • 如果您可以重现问题,请进行 API 调用并重现 502 Bad Gateway 错误。
  2. 选择其中一个失败的请求并检查跟踪记录。
  3. 浏览跟踪记录的不同阶段,并找到失败的位置。
  4. 紧跟在从目标服务器收到响应阶段之后进入错误阶段,如下所示:

    记下跟踪记录中的错误值:

    • 错误Body buffer overflow
    • error.classcom.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. 进入从目标服务器收到的响应阶段,如下所示,适用于不同的场景:

    未压缩

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

    记下跟踪记录中的错误值:

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

    压缩后

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

    记下跟踪记录中的错误值:

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

    {"fault":{"faultstring":"Body buffer overflow","detail":{"errorcode":"protocol.http.TooBigBody"}}}
    
  9. 进入跟踪记录中的 AX(已记录 Google Analytics(分析)数据)阶段,然后点击该阶段以查看相关详情。

  10. Phase Details(阶段详细信息)中向下滚动到 Variables Read(变量读取)部分,并确定 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. 如果您是 Private Cloud 用户,则可以使用 NGINX 访问日志来确定有关 HTTP 502 错误的关键信息。
  2. 检查 NGINX 访问日志:

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

    其中:将 ORGENVPORT# 替换为实际值。

  3. 搜索以查看在特定时间段内是否存在任何 502 错误(如果问题是在过去发生的),或者是否有任何请求仍然失败并显示 502
  4. 如果您确实发现任何 502 错误且 X-Apigee-fault-code protocol.http.TooBigBody 的值匹配,请确定 X-Apigee-fault-code 的值。

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

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

    响应标头
    X-Apigee-fault-code protocol.http.TooBigBody
    X-Apigee-fault-source target

原因:响应载荷大小大于允许的限制

诊断

  1. 根据场景 1 的常见诊断步骤部分的说明,使用 API 监控、跟踪工具或 NGINX 访问日志确定所观察到的错误的错误代码故障来源响应载荷大小
  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. 按照场景 2 的常见诊断步骤中所述,确定使用 API 监控、跟踪工具或 NGINX 访问日志观察到的错误的错误代码故障来源响应载荷大小
  2. 如果故障来源的值为 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 限制以及响应标头 target.received.content.length 之间,这就是导致此错误的原因。

    实际请求

    使用实际请求

    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. 如果您是 Private Cloud 用户,则可以使用消息处理器日志来确定有关 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 中的行与以下内容类似(TotalReadchunkCount 可能因您的情况而异):
      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 宣传信息:签名网址生成器示例所示。

流式处理

方法 3:使用流式传输

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

CwC

方法 4:使用 CwC 属性提高缓冲区限制

仅应在无法使用任何推荐选项时使用此选项,因为如果增加默认大小,可能会导致性能问题。

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

限制

Apigee 要求客户端应用和后端服务器发送的载荷大小不超过 Apigee Edge 限制中针对 Request/response size 所述的允许限制。

  1. 如果您是公有云用户,则请求和响应载荷大小的上限具体说明见 Apigee Edge 限制中的 Request/response size
  2. 如果您是 Private Cloud 用户 ,则可能修改了请求和响应载荷的默认上限(尽管不建议这样做)。您可以按照如何查看当前限制中的说明确定请求载荷大小上限。

如何查看当前的上限?

本部分介绍如何验证属性 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 中,针对私有云配置的请求载荷大小限制为 10 MB

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

必须收集的诊断信息

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

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

  • 组织名称
  • 环境名称
  • API 代理名称
  • 用于重现 502 错误的完整 curl 命令
  • API 请求的跟踪文件
  • 来自目标/后端服务器的响应的完整输出以及载荷的大小

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

  • 观察到失败请求的完整错误消息
  • 组织名称
  • 环境名称
  • API 代理软件包
  • 失败 API 请求的跟踪文件
  • 用于重现 502 错误的完整 curl 命令
  • 来自目标/后端服务器的响应的完整输出以及载荷的大小
  • NGINX 访问日志 /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log

    其中:将 ORGENVPORT# 替换为实际值。

  • 消息处理器系统日志 /opt/apigee/var/log/edge-message-processor/logs/system.log