500 内部服务器错误 - 已启用流式传输

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

问题

客户端应用收到针对 API 调用的 HTTP 响应状态代码 500 及消息 Internal Server Error

错误消息

客户端应用可能会收到错误响应,如下所示:

HTTP/1.1 500 Internal Server Error

后面可能会显示类似如下的错误消息:

{
   "fault":{
      "faultstring":"Expecting } at line 1"
      "detail":{
         "errorcode":"Internal Server Error"
      }
   }
}

OR

{
   "fault":{
      "faultstring":"Expecting ] at line 1"
      "detail":{
         "errorcode":"Internal Server Error"
      }
   }
}

可能的原因

导致出现 500 内部服务器错误的原因有很多。本指南重点介绍启用流式传输时访问请求/响应载荷导致的 500 内部服务器错误。

原因 说明 谁可以执行问题排查步骤
在启用流式传输的情况下访问载荷 由于启用流式传输时访问了请求/响应载荷,因此发生错误。 Edge 私有云和公有云用户

原因:在启用流式传输的情况下访问载荷

诊断

过程 1:使用 Trace

  1. 启用跟踪会话,然后进行 API 调用以重现问题 - 500 Internal Server Error。
  2. 选择其中一个失败的请求并检查跟踪记录。
  3. 浏览跟踪记录的各个阶段,并找到失败的位置。
  4. 在政策解析请求/响应载荷时,可能会发生此错误。
  5. 以下轨迹屏幕截图示例显示了 JSONThreatProtection 政策JSONThreatProtection 失败,并显示错误 JSONThreatProtection

    alt_text

    记下轨迹输出中的以下信息,如上方屏幕截图所示:

    失败政策 :JSONThreatProtection

    流程:代理请求

  6. 检查失败的政策定义并检查正在解析的载荷。

    在示例场景中,检查名为 JSON-Threat-Protection 的已失败 JSONThreatProtection 政策,并检查 <Source> 元素。

    <JSONThreatProtection async="false" continueOnError="false" enabled="true" name="JSON-Threat-Protection">
       <DisplayName>JSON Threat Protection</DisplayName>
       <ArrayElementCount>20</ArrayElementCount>
       <ContainerDepth>10</ContainerDepth>
       <ObjectEntryCount>15</ObjectEntryCount>
       <ObjectEntryNameLength>50</ObjectEntryNameLength>
       <Source>request</Source>
       <StringValueLength>1000</StringValueLength>
    </JSONThreatProtection>
    

    请注意,<Source> 元素指向 request.。这意味着解析请求载荷时出错。

  7. 通过检查 API 请求确定要解析的载荷类型。
  8. 您可以查看 API 请求中的请求载荷和 Content-Type 标头的内容。在以下示例 curl 命令中,使用的是 JSON 载荷。

    curl -i https://VIRTUAL_HOST_ALIAS/BASEPATH -H "Content-Type: application/json" \
    -X POST -d @request-payload.json

    您还可以检查失败的政策,并确定正在解析的载荷类型。在上面的示例场景中,JSON-Threat-Protection 政策失败。 这表示载荷必须采用 JSON 格式。

  9. 验证载荷的格式是否正确。如果载荷无效,您可能会遇到此错误。

  10. 如果载荷有效,但您仍收到错误消息部分中列出的错误,则这些错误的原因是启用流式传输时正在访问载荷。

    根据政策解析的载荷(如第 6 步中确定),在适当的阶段检查 Trace 工具中的载荷内容。

    在示例场景中,系统正在解析请求载荷,因此请检查跟踪记录中的“Request Received from Client”阶段,并检查请求内容

    alt_text

    如果发现“请求内容”为空(如上方屏幕截图所示),即使您发送了有效的载荷,也表示导致此问题的可能原因是启用了请求流式传输

    这是因为启用流式传输后,请求载荷将不会显示在跟踪记录中。

    同样,如果在出现错误时解析响应载荷,请在从目标服务器接收到的响应阶段检查响应内容。

  11. 接下来,根据在 API 代理流中使用失败政策的位置,检查代理和目标端点的定义。验证是否启用了直播功能。

    在示例场景中,失败政策是在代理请求流程中执行的(如上文第 5 步确定);因此,请检查代理端点:

    <ProxyEndpoint name="default">
    ...
      <HTTPProxyConnection>
        <BasePath>/v1/weather</BasePath>
        <VirtualHost>secure</VirtualHost>
        <Properties>
          <Property name="response.streaming.enabled">true</Property>
          <Property name="request.streaming.enabled">true</Property>
        </Properties>
      </HTTPProxyConnection>
    </ProxyEndpoint>
    

    如上例所示,请求流式传输已启用,如属性 "request.streaming.enabled" 设置为 true 所示。

    因此,错误原因在于 API 代理中使用了 JSONThreatProtection 政策,该政策在启用流式传输功能后访问请求载荷。这会导致错误,因为它在 API 代理中触发缓冲,并违背了在 Apigee Edge 中使用流式传输的目的。

    使用较小的载荷时,可能不会出现此错误,但如果您使用较大的载荷,则会看到这些错误。

  12. 您可以按以下步骤检查跟踪记录中"X-Apigee-fault-source"阶段中“"X-Apigee-fault-source"的值,验证 500 错误是否是由此政策引起的:
    1. 点击 "AX"(Google Analytics(分析)数据记录)阶段,如以下屏幕截图所示:

      alt_text

    2. 将“阶段详细信息”向下滚动到“Error Headers”部分,并 确定“X-Apigee-fault-code”“X-Apigee-fault-source”“X-Apigee-fault-policy”的值,如下所示:

      alt_text

    3. 如果 "X-Apigee-fault-source" 的值为 "policy"(如上图所示),则表示错误是由在启用流式传输时访问载荷的政策导致的。

分辨率

反模式:在启用流式传输的情况下访问请求/响应载荷中所述,在启用流式传输的情况下访问载荷是一种反模式。

  1. 如果要处理载荷,则需要通过移除 "request.streaming.enabled" and "response.streaming.enabled" 属性在代理/目标端点中停用流式传输,如下面的示例 ProxyEndpoint 中所示:
    <ProxyEndpoint name="default">
    ...
      <HTTPProxyConnection>
        <BasePath>/v1/weather</BasePath>
        <VirtualHost>secure</VirtualHost>
      </HTTPProxyConnection>
    </ProxyEndpoint>
    

    或者

  2. 如果您希望为 API 代理使用流式传输,请不要在 API 代理中使用访问请求/响应载荷的任何政策。

注意

  • 在本 playbook 中,示例场景中使用了 JSONThreatProtection 政策在启用了流式传输的情况下处理请求载荷。这会导致 500 个带有不同错误的内部服务器错误。
  • 这些错误也可能在使用 JSONToXML 和 XMLToJSON 等政策时出现,这些政策会在启用流式传输时处理请求或响应载荷。
  • 我们强烈建议不要在启用流式传输时在需要访问载荷的代理中使用任何此类政策。
  • 这样做是一种反模式,如反模式:在启用流式传输时访问请求/响应载荷中所述。

使用 API Monitoring 诊断问题

如果您是 Private Cloud 用户,请跳过此步骤。

借助 API 监控功能,您可以快速隔离有问题的方面,从而诊断错误、性能和延迟问题及其来源,例如开发者应用、API 代理、后端目标或 API 平台。

通过一个示例场景演示了如何使用 API Monitoring 排查 API 的 5xx 问题。例如,您可能需要设置提醒,以便在 500 个错误的数量超过特定阈值时收到通知。

如果您希望在政策抛出 500 错误响应时收到通知,则需要将提醒设为 500 状态代码,并将故障来源设为代理

必须收集诊断信息

如果在按照上述说明操作后问题仍然存在,请收集以下诊断信息。请与 Apigee 支持团队联系并进行分享。

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

  • 组织名称
  • 环境名称
  • API 代理名称
  • 请完成 curl 命令以及请求载荷(如果有),以重现 500 错误
  • 包含“500 Internal Server Error”这项请求的跟踪文件
  • 如果 500 错误目前没有发生,请提供过去出现 500 错误时的时区信息对应的时间段。

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

  • 观察到失败请求的完整错误消息
  • 您观察到 500 错误的组织、环境名称和 API 代理名称
  • API 代理软件包
  • 请求中使用的载荷(如果有)
  • 包含“500 Internal Server Error”这项请求的跟踪文件
  • NGINX 访问日志 (/opt/apigee/var/log/edge-router/nginx/ <org>~ <env>.<port#>_access_log)
  • 消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log)
  • 发生 500 错误时包含时区信息的时间段。