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 公有云和私有云用户

常见诊断步骤

确定失败请求的消息 ID

跟踪工具

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

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

    “Stage Details”(阶段详细信息)部分中的消息 ID

NGINX 访问日志

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

您还可以参考 NGINX 访问日志来确定 503 错误的消息 ID。如果问题是过去发生的,或者问题是间歇性的,并且您无法在界面中捕获跟踪记录,这种方法特别有用。如需通过 NGINX 访问日志确定此信息,请按以下步骤操作:

  1. 查看 NGINX 访问日志:(/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log)
  2. 搜索特定 API 代理在特定持续时间内是否存在任何 503 错误(如果问题是在过去发生的),或者是否有任何请求仍然失败并显示 503
  3. 如果 X-Apigee-fault-code messages.adaptors.http.flow.ServiceAvailable 出现任何 503 错误,请记下一个或多个此类请求的消息 ID,如以下示例所示:

    显示 503 错误的示例条目

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

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

诊断

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

      alt_text

    2. 使用“跟踪”工具(如常见诊断步骤中所述),并验证您是否在 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: Broken pipe

      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. 在数据包 58 91011 中,消息处理器继续将请求载荷发送到后端服务器。
    3. 在数据包 67 中,后端服务器针对从消息处理器收到的请求载荷的一部分,使用 ACK 进行响应。
    4. 不过,在数据包 12 中,后端服务器不再针对收到的应用数据包使用 ACK 进行响应,随后使用响应载荷做出响应,而是使用 FIN ACK 进行响应,从而关闭连接。
    5. 这清楚地表明,在消息处理器仍在发送请求载荷时,后端服务器过早关闭连接。
    6. 这会导致消息处理器记录 IOException: Broken Pipe 错误并向客户端返回 503

分辨率

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

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

必须收集的诊断信息

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

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

  • 组织名称
  • 环境名称
  • API 代理名称
  • 完成 curl 命令以重现 503 错误
  • 包含带有 503 Service Unavailable 错误的请求的跟踪文件
  • 如果当前未发生 503 错误,请提供过去发生 503 错误时的时区信息对应的时间段。

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

  • 观察到失败请求的完整错误消息
  • 您观察到 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