503 服务不可用 - 后端服务器过早关闭

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

问题

客户端应用在调用 API 代理后收到 HTTP 响应状态 503,并显示消息 Service Unavailable。

出错提示

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

HTTP/1.1 503 Service Unavailable

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

{
   "fault": {
      "faultstring": "The Service is temporarily unavailable",
      "detail": {
           "errorcode": "messaging.adaptors.http.flow.ServiceUnavailable"
       }
    }
}

可能的原因

原因 说明 适用的问题排查说明
目标服务器过早关闭连接 在消息处理器仍在发送请求载荷时,目标服务器过早结束连接。 Edge Public 和 Private Cloud 用户

常见诊断步骤

确定失败请求的消息 ID

Trace 工具

如需使用 Trace 工具确定失败请求的消息 ID,请执行以下操作:

  1. 如果问题仍然存在,请为受影响的 API 启用 跟踪会话。
  2. 进行 API 调用并重现问题 - 503 Service Unavailable 错误代码为 messaging.adaptors.http.flow.ServiceUnavailable.
  3. 选择其中一个失败的请求。
  4. 前往 AX 阶段,然后在阶段详情部分中向下滚动,确定请求的消息 ID (X-Apigee.Message-ID),如下图所示。

    “阶段详情”部分中的消息 ID

NGINX 访问日志

如需使用 NGINX 访问日志确定失败请求的消息 ID,请执行以下操作:

您还可以参考 NGINX 访问日志来确定 503 错误的 message ID。 如果过去曾发生过该问题或者该问题间歇性发生,并且您无法在界面中捕获跟踪记录,则此功能特别有用。您可以按照以下步骤从 NGINX 访问日志中确定此信息:

  1. 检查 NGINX 访问日志:(/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log)
  2. 搜索以查看在特定时间段内(如果问题发生在过去)特定 API 代理是否存在任何 503 错误,或者是否仍有请求失败并显示 503。
  3. 如果存在任何 503 错误,且包含 X-Apigee-fault-code messaging.adaptors.http.flow.ServiceUnavailable,请记下相应请求的消息 ID,如以下示例所示:

    显示 503 错误的条目示例

    显示状态代码、消息 ID、故障源和故障代码的示例条目

原因:目标服务器过早关闭连接

诊断

  1. 如果您是公共云或私有云用户:
    1. 使用 Trace 工具(如常见诊断步骤中所述),并在已记录的 Analytics 数据窗格中验证您是否已设置以下两项:
      • X-Apigee.fault-code: messaging.adaptors.http.flow.ServiceUnavailable
      • X-Apigee.fault-source: target

      alt_text

    2. 使用 Trace 工具(如常见诊断步骤中所述),并验证您是否在 TARGET_REQ_FLOW state 属性之后的 Error 窗格中设置了以下两项:
      • error.class: com.apigee.errors.http.server.ServiceUnavailableException
      • error.cause:: Broken pipe

      alt_text

    3. 如需进一步调查,请参阅使用 tcpdump。
  2. 如果您是 Private Cloud 用户:
    • 确定失败请求的消息 ID。
    • 在消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log) 中搜索相应消息 ID。
    • 您将看到以下某项异常:

      异常 #1:java.io.IOException:写入到通道 ClientOutputChannel 时发生管道损坏

      2021-01-30 15:31:14,693 org:anotherorg env:prod api:myproxy
      rev:1 messageid:myorg-opdk-test-1-30312-13747-1  NIOThread@1
      INFO  HTTP.SERVICE - ExceptionHandler.handleException() :
      Exception java.io.IOException: Broken pipe occurred while writing to channel
      ClientOutputChannel(ClientChannel[Connected:
      Remote:IP:PORT Local:0.0.0.0:42828]@8380 useCount=1
      bytesRead=0 bytesWritten=76295 age=2012ms  lastIO=2ms  isOpen=false)

      或

      异常 #2:onExceptionWrite 异常:{}
      java.io.IOException:管道损坏

      2021-01-31 15:29:37,438 org:anotherorg env:prod api:503-test
      rev:1 messageid:leonyoung-opdk-test-1-18604-13978-1
      NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context$2.onException() :
      ClientChannel[Connected: Remote:IP:PORT
      Local:0.0.0.0:57880]@8569 useCount=1 bytesRead=0 bytesWritten=76295 age=3180ms  lastIO=2
      ms  isOpen=false.onExceptionWrite exception: {}
      java.io.IOException: Broken pipe
    • 这两种异常都表明,在消息处理器仍在向后端服务器写入请求载荷时,连接被后端服务器过早关闭。因此,消息处理器会抛出异常 java.io.IOException: Broken pipe。
    • Remote:IP:PORT 表示已解析的后端服务器 IP 地址和端口号。
    • 上述错误消息中的属性 bytesWritten=76295 表示,在连接过早关闭时,消息处理器已向后端服务器发送了 76295 字节的载荷。
    • 属性 bytesRead=0 表示消息处理器尚未从后端服务器收到任何数据(响应)。
    • 如需进一步调查此问题,请在后端服务器或消息处理器上收集 tcpdump,然后按照下文所述进行分析。

使用 tcpdump

  1. 使用以下命令在后端服务器或消息处理器上捕获 tcpdump:

    用于在后端服务器上收集 tcpdump 的命令:

    tcpdump -i any -s 0 host MP_IP_ADDRESS -w FILE_NAME
    

    用于在消息处理器上收集 tcpdump 的命令:

    tcpdump -i any -s 0 host BACKEND_HOSTNAME -w FILE_NAME
    
  2. 分析 tcpdump 捕获的内容:

    示例 tcpdump 输出(在消息处理器上收集):

    alt_text

    在上述 tcpdump 中,您可以看到以下内容:

    1. 在数据包 4 中,消息处理器向后端服务器发送了 POST 请求。
    2. 在数据包 5、8、 9、10、11 中,消息处理器继续向后端服务器发送请求载荷。
    3. 在数据包 6 和 7 中,后端服务器针对从消息处理器收到的部分请求载荷响应了 ACK。
    4. 不过,在数据包 12 中,后端服务器没有针对收到的应用数据包响应 ACK,也没有随后响应响应载荷,而是响应 FIN ACK 来启动连接关闭。
    5. 这清楚地表明,在消息处理器仍在发送请求载荷时,后端服务器过早关闭了连接。
    6. 这会导致消息处理器记录 IOException: Broken Pipe 错误并向客户端返回 503

分辨率

  1. 与您的应用团队和/或网络团队合作,分析并修复后端服务器端过早断开连接的问题。
  2. 确保后端服务器应用在收到整个请求载荷之前不会超时或重置连接。
  3. 如果您在 Apigee 和后端服务器之间有任何中间网络设备或层,请确保它们不会在收到整个请求载荷之前超时。

如果问题仍然存在,请转到必须收集诊断信息。

必须收集的诊断信息

如果按照上述说明操作后问题仍然存在,请收集以下诊断信息,然后联系 Apigee Edge 支持团队:

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

  • 组织名称
  • 环境名称
  • API 代理名称
  • 用于重现 503 错误的完整 curl 命令
  • 包含 503 Service Unavailable 错误的请求的轨迹文件
  • 如果目前未发生 503 错误,请提供过去发生 503 错误的时间段(包含时区信息)。

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

  • 失败请求的完整错误消息
  • 您正在观察 503 错误的组织、环境名称和 API 代理名称
  • API 代理软件包
  • 包含 503 Service Unavailable 错误的请求的轨迹文件
  • NGINX 访问日志
    /opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log
  • 消息处理器日志
    /opt/apigee/var/log/edge-message-processor/logs/system.log
  • 发生 503 错误的时间段(包含时区信息)
  • Tcpdumps 在发生错误时收集的消息处理器和后端服务器上的信息