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

您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
info

问题

对于 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 Internal Server Error 可能是由多种不同的原因造成的。本剧本 重点介绍在启用流式传输 时访问请求/响应 载荷而导致的 500 Internal Server Error

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

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

诊断

过程 1:使用跟踪记录

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

    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 步中所确定), 在相应阶段的跟踪记录工具中检查载荷内容。

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

    alt_text

    如果在发送有效载荷的情况下,请求内容仍为空(如上图所示),则表示此问题很可能是由启用了请求流式传输导致的。

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

    同样,如果在发生错误时正在解析响应载荷,请检查 "Response received from target server" 阶段中的响应内容。

  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>

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

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

    对于较小的载荷,您可能不会看到此错误,但当您使用较大的载荷时,您 会看到这些错误。

  12. 您可以使用以下步骤,通过检查跟踪记录的 "AX" (分析数据已记录)阶段中 "X-Apigee-fault-source" 的值 ,验证 500 错误是否是由政策导致的:
    1. 点击"AX"(分析数据已记录)阶段,如下图所示:

      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 代理中使用任何访问请求/响应载荷的政策。

注意:

  • 在本剧本中,JSONThreatProtection 政策用于在示例场景中处理启用了流式传输的请求载荷,其中包含 。这导致了 500 Internal Server Error,并显示不同的错误。
  • 对于 JSONToXML 和 XMLToXML 等政策,您也可以看到这些错误,这些政策会在启用流式传输的情况下处理 请求或响应载荷。
  • 我们强烈建议您不要在需要访问 载荷的代理中使用任何此类政策。
  • 这样做是一种反模式,如 反模式:在启用流式传输时访问请求/响应载荷中所述。

使用 API 监控诊断问题

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

API 监控可让您快速找出问题区域,以诊断错误、性能和延迟时间问题及其来源,例如开发者应用、API 代理、后端目标或 API 平台。

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

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

必须收集的诊断信息

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

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

  • 组织名称
  • 环境名称
  • 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 错误的时间段以及时区信息。