504 Gateway Timeout

<ph type="x-smartling-placeholder"></ph> 您正在查看 Apigee Edge 文档。
转到 Apigee X 文档
信息

问题

客户端应用收到 HTTP 状态代码 504 以及消息 Gateway Timeout 作为对 API 调用的响应。

HTTP 状态代码 504 Gateway Timeout 错误表示客户端 未及时从边缘网关或后端服务器收到 API

错误消息

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

HTTP/1.1 504 Gateway Timeout

在某些情况下,可能还会看到以下错误消息:

{
   "fault": {
      "faultstring": "Gateway Timeout",
      "detail": {
           "errorcode": "messaging.adaptors.http.flow.GatewayTimeout"
       }
    }
}

哪些原因会导致网关超时?

通过 Edge 平台发出的 API 请求的一般路径为客户端 ->路由器 ->消息处理器 ->后端服务器,如下图所示:

Edge 平台中的客户端应用、路由器和消息处理器通过 合适的超时值。Edge 平台预期在特定时间段内发送响应 根据超时值确定每个 API 请求的超时时长如果您在以下期限内没有收到回复, 指定的时间段,则返回 504 Gateway Timeout Error

下表详细说明了 Edge 中何时可能会发生超时:

发生超时情况 详细信息
消息处理器上发生超时
  • 后端服务器未在指定超时时间内响应消息处理器 消息处理器上的超时。
  • 消息处理器超时,并将响应状态作为 504 Gateway Timeout 发送到路由器。
路由器上发生超时
  • 消息处理器未在指定的超时时间内响应路由器 出现故障。
  • 路由器超时,并将响应状态作为 504 Gateway Timeout 发送到客户端应用。
客户端应用超时
  • 路由器未在指定的超时内响应客户端应用 出现故障。
  • 客户端应用超时,并结束向最终用户返回 504 Gateway Timeout 响应状态。

可能的原因

在 Edge 中,504 Gateway Timeout 错误的常见原因如下:

原因 详细信息 指定步骤
后端服务器速度缓慢 正在处理 API 请求的后端服务器因负载过重或 性能不佳。 公有云和私有云用户
Edge 处理 API 请求的速度缓慢 由于负载高或性能低,Edge 需要很长时间来处理 API 请求 性能

慢速 后端服务器

如果后端服务器速度很慢或需要很长时间来处理 API 请求,那么 您会收到 504 Gateway Timeout 错误。如上一部分所述,超时 在以下情形之一中会发生:

  1. 在后端服务器响应之前,消息处理器超时。
  2. 路由器在消息处理器/后端服务器响应之前超时。
  3. 在路由器/消息处理器/后端服务器响应之前,客户端应用超时。

以下各部分介绍了如何根据上述各项来诊断和解决问题 场景。

情景 #1 在后端服务器响应之前,消息处理器超时

诊断

您可以使用以下过程来诊断是否发生了 504 Gateway Timeout 错误 因为后端服务器运行缓慢

步骤 1 使用 Trace

如果问题仍未解决(仍然出现 504 个错误),请按以下方法操作 步骤:

  1. 在 Edge 界面中跟踪受影响的 API。请等待错误发生,或者 API 调用,然后进行一些 API 调用并重现 504 Gateway Timeout 错误。
  2. 发生错误后,检查特定请求,该请求的响应代码显示为 504
  3. 检查每个阶段所用的时间,并记下时间最多的阶段 。
  4. 如果您发现最长耗时的错误, 则表示后端服务器运行缓慢或需要很长时间 处理请求: <ph type="x-smartling-placeholder">
      </ph>
    • 请求已发送到目标服务器
    • ServiceCallout 政策

以下示例提供了一个跟踪记录,显示后端服务器在 55 秒后导致 504 Gateway Timeout 错误:

在上述跟踪记录中,消息处理器会在 55002 毫秒后超时,就像后端服务器一样 没回应。

步骤 2 使用消息处理器日志

  1. 检查消息处理器的日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log)
  2. 如果您发现特定 API 代理请求的 Gateway TimeoutonTimeoutRead 错误 在特定时间,则表示消息处理器已超时。

    显示网关超时错误的消息处理器日志示例

    2015-09-29 20:16:54,340 org:myorg env:staging api:profiles rev:13 NIOThread@1
    ERROR ADAPTORS.HTTP.FLOW - AbstractResponseListener.onException() :
    AbstractResponseListener.onError(HTTPResponse@4d898cf1, Gateway
    Timeout)
    2015-09-29 20:16:57,361 org:myorg env:staging api:profileNewsletters rev:8
    NIOThread@0 ERROR HTTP.CLIENT - HTTPClient$Context$3.onTimeout() :
    SSLClientChannel[C:XX.XX.XX.XX:443 Remote
    host:192.168.38.54:38302]@120171 useCount=2 bytesRead=0
    bytesWritten=824 age=55458ms lastIO=55000ms .onTimeoutRead
    

    在上面的消息处理器日志中,您注意到后端服务器使用 IP 地址 XX.XX.XX.XX 即使在 55 秒后也未响应(lastIO=55000ms)。 因此,消息处理器超时并发送 504 Gateway Timeout 错误。

    检查以下内容:如何控制消息处理器上的超时?

    • 消息处理器上的超时控制方式。消息处理器通常是 (默认超时值为 55 秒)通过 HTTPTransport.io.timeout.millis。该超时值为 适用于属于由此服务的组织的所有 API 代理。 消息处理器。
      • 如果后端服务器在 55 秒内未响应,则消息 处理器超时,并向客户端发送 504 Gateway Timeout 错误。
    • 消息处理器中指定的超时值可以是 已被属性 io.timeout.millis 替换 。此超时值适用于特定 API 用于指定上述属性的代理。例如,如果 在 API 代理中将 io.timeout.millis 设置为 10 秒,则 超时值 10 秒将用于此特定 API 代理。
      • 如果后端服务器在 10 秒内没有针对 API 代理,那么消息处理器会超时并发送 504 Gateway Timeout 错误。

分辨率

  1. 检查后端服务器花费的时间超过 55 秒的原因,看看能否解决问题 从而加快响应速度
  2. 如果无法修复/优化后端服务器,或者已知后端 服务器花费的时间比配置的超时时间长,那么 请将路由器和消息处理器的超时值增加为合适的值。

场景 #2 - 在消息处理器/后端服务器响应之前,路由器超时

如果路由器在消息显示前超时,您可能会收到 504 Gateway Timeout 错误 处理器/后端服务器响应。如果出现以下任一情况,就可能会发生这种情况:

  • 路由器上设置的超时值短于消息中设置的超时值 处理器。例如,假设路由器上的超时时间为 50 秒,而消息 处理器为 55 秒。
    路由器超时 消息处理器超时
    50 秒 55 秒
  • 使用 在目标端点配置中设置的 io.timeout.millis 属性 该 API 代理的以下功能:

    例如,如果设置了以下超时值:

    路由器超时 消息处理器超时 API 代理中的超时
    57 秒 55 秒 120 秒

    但是,在 API 代理中,io.timeout.millis 设置为 120 秒:

    <HTTPTargetConnection>
         <Properties>
              <Property name="io.timeout.millis">120000</Property>
          </Properties>
          <URL>http://www.apigee.com</URL>
    </HTTPTargetConnection>
    

    然后,消息处理器在 55 秒后也不会超时,即使处于超时状态 值(55 秒)小于路由器上的超时值(57 秒)。这是因为 消息处理器上的 55 秒超时值会被替换为 在 API 代理中设置的 120 秒。因此,消息处理器的超时值 为 120 秒

    由于路由器的超时值(57 秒)低于在 API 代理,如果后端服务器在 57 小时后没有响应,则路由器将超时 。

诊断

  1. 查看 NGINX 访问日志 (/opt/apigee/var/log/edge-router/nginx/ORG~ENV.PORT#_access_log)
  2. 如果路由器在消息处理器之前超时,您将看到 504 的状态 访问 NGINX 访问日志,查看 API 请求的 message id 消息处理器将设置为 -。这是因为路由器未收到任何响应 在路由器设置的超时时限内从消息处理器中发送。

    NGINX 日志条目示例,显示由于路由器超时而导致的 504

  3. 在上面的示例中,请注意 NGINX 上 504 的状态,即 Message 处理器为 -,总播放时间为 57.001 秒。这是因为路由器超时 57.001 秒后我们没有收到消息处理器的任何响应。
  4. 在这种情况下,您会在消息中看到 Broken Pipe 异常 处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log).)
    2017-06-09 00:00:25,886 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-mp01-18869-23151-1  NIOThread@1 INFO  HTTP.SERVICE - ExceptionHandler.handleException() : Exception java.io.IOException: Broken pipe occurred while writing to channel ClientOutputChannel(ClientChannel[A:XX.XX.XX.XX:8998 Remote host:YY.YY.YY.YY:51400]@23751 useCount=1 bytesRead=0 bytesWritten=486 age=330465ms  lastIO=0ms )
    2017-06-09 00:00:25,887  org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-mp01-18869-23151-1  NIOThread@1 INFO  HTTP.SERVICE - ExceptionHandler.handleException() : Exception trace:
    java.io.IOException: Broken pipe
            at com.apigee.nio.channels.ClientOutputChannel.writePending(ClientOutputChannel.java:51) ~[nio-1.0.0.jar:na]
            at com.apigee.nio.channels.OutputChannel.onWrite(OutputChannel.java:116) ~[nio-1.0.0.jar:na]
            at com.apigee.nio.channels.OutputChannel.write(OutputChannel.java:81) ~[nio-1.0.0.jar:na]
    <snipped>
    

之所以显示此错误,是因为路由器超时后会断开与 消息处理器。当消息处理器完成处理时,它会尝试向 对路由器做出响应由于与路由器的连接已经关闭,因此您会收到 针对消息处理器的 Broken Pipe exception 权限。

在上述情况下预计会出现此例外情况。因此,实际 导致 504 Gateway Timeout 错误的原因是后端服务器需要较长的响应时间 您需要解决该问题。

分辨率

  1. 如果是自定义后端服务器,那么 <ph type="x-smartling-placeholder">
      </ph>
    1. 检查后端服务器响应时间过长的原因,看看能否 从而加快响应速度
    2. 如果无法修复/优化后端服务器,或者已知 请增加超时值, 路由器和消息处理器

      创意:根据以下示例,为不同组件设置超时值 订单:

      客户端超时 >路由器超时 >消息超时 处理器 >API 代理中的超时

  2. 如果是 NodeJS 后端服务器,则: <ph type="x-smartling-placeholder">
      </ph>
    1. 检查 NodeJS 代码是否调用任何其他后端服务器, 才能返回响应。检查后端服务器用时较长的原因,并 适当地解决问题。
    2. 检查消息处理器是否遇到了较高的 CPU 或内存使用率: <ph type="x-smartling-placeholder">
        </ph>
      1. 如果任何消息处理器的 CPU 使用率较高,则生成三个 线程 每 30 秒进行一次转储 dumps
        JAVA_HOME/bin/jstack -l PID > FILENAME
      2. 如果任何消息处理器的内存用量较高,则生成 堆 dump
        sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
      3. 使用以下命令重启消息处理器。这应该会降低 和内存:
        /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
      4. 监控 API 调用以确认问题是否仍然存在。
      5. 请与 Apigee Edge 支持团队联系并提供 线程转储、堆转储和消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log), 调查 CPU/内存用量高的原因。

了解详情:如何针对 Message 上的 NodeJS 后端服务器控制超时 处理器

  • NodeJS 后端服务器在消息处理器的 JVM 进程中运行。通过 NodeJS 后端服务器的超时值,通过 nodejs.properties 文件中的 http.request.timeout.seconds。这个 属性设置为 0,即默认情况下,所有发生超时的 属于由此消息处理器所提供服务的组织的 API 代理。因此,即使 NodeJS 后端服务器需要很长时间,消息处理器不会超时。
  • 不过,如果 NodeJS 后端服务器耗时较长, 请求大于57 秒后,路由器将超时并发送 504 Gateway Timeout 错误。

情景 #3 - 客户端应用在路由器/消息处理器/后端服务器之前超时 回复

如果客户端应用在504 Gateway Timeout 。如果出现以下情况,则可能会出现这种情况:

  1. 客户端应用中设置的超时值低于 路由器和消息处理器:

    例如,如果设置了以下超时值:

    客户端超时 路由器超时 消息处理器超时
    50 秒 57 秒 55 秒

    在这种情况下,通过 Edge 获取 API 请求响应所需的总时间 小于等于 50 秒。这包括发出 API 请求所用的时间, 由 Edge(路由器、消息处理器)处理,请求将发送到后端服务器 (如果适用)、后端处理请求并发送响应、Edge 处理 最后将其发送回客户端

    如果路由器在 50 秒内没有响应客户端,那么客户端将 超时并断开与路由器的连接。客户端将收到 504

    这会使 NGINX 设置状态代码 499,表示客户端已关闭 连接。

诊断

  1. 如果客户端应用在收到来自路由器的响应之前超时,那么它将 断开与路由器的连接。在这种情况下,您会在 特定 API 请求的 NGINX 访问日志。

    显示状态代码 499 的 NGINX 日志条目示例

  2. 请注意,在上面的示例中,NGINX 上 499 的状态和总耗时为 50.001 秒。这表示客户端在 50.001 秒后超时。
  3. 在这种情况下,您会在消息中看到 Broken Pipe 个异常 处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log).
    )
    2017-06-09 00:00:25,886 org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-1-11193-11467656-1  NIOThread@1 INFO  HTTP.SERVICE - ExceptionHandler.handleException() : Exception java.io.IOException: Broken pipe occurred while writing to channel ClientOutputChannel(ClientChannel[A:XX.XX.XX.XX:8998 Remote host:YY.YY.YY.YY:51400]@23751 useCount=1 bytesRead=0 bytesWritten=486 age=330465ms  lastIO=0ms )
    2017-06-09 00:00:25,887  org:myorg env:test api:myapi-v1 rev:23 messageid:rrt-1-11193-11467656-1  NIOThread@1 INFO  HTTP.SERVICE - ExceptionHandler.handleException() : Exception trace:
    java.io.IOException: Broken pipe
            at com.apigee.nio.channels.ClientOutputChannel.writePending(ClientOutputChannel.java:51) ~[nio-1.0.0.jar:na]
            at com.apigee.nio.channels.OutputChannel.onWrite(OutputChannel.java:116) ~[nio-1.0.0.jar:na]
            at com.apigee.nio.channels.OutputChannel.write(OutputChannel.java:81) ~[nio-1.0.0.jar:na]
    <snipped>
    
  4. 路由器超时后,会关闭与消息处理器的连接。当 消息处理器完成其处理,并尝试将响应写入路由器。 由于与路由器的连接已关闭,您将在消息处理器上获得 Broken Pipe exception
  5. 在上述情况下,这种例外情况属于正常情况。所以造成这种情况的 504 Gateway Timeout 错误仍然在于后端服务器需要很长时间才能做出响应, 您需要解决该问题。

分辨率

  1. 如果这是您的自定义后端服务器,则: <ph type="x-smartling-placeholder">
      </ph>
    1. 检查后端服务器,确定用时超过 57 秒的原因,并查看是否 可以进行修复/优化,以提高响应速度。
    2. 如果无法修复/优化后端服务器,或者您知道 然后增加超时值, 路由器和消息处理器

      创意:根据以下示例,为不同组件设置超时值 订单:

      客户端超时 >路由器超时 >消息超时 处理器 >API 代理中的超时

  2. 如果是 NodeJS 后端,则: <ph type="x-smartling-placeholder">
      </ph>
    1. 检查 NodeJS 代码是否调用了任何其他后端服务器, 需要很长时间才能返回检查这些后端服务器花费的时间较长的原因。
    2. 检查消息处理器是否遇到了较高的 CPU 或内存使用率: <ph type="x-smartling-placeholder">
        </ph>
      1. 如果消息处理器的 CPU 使用率较高,则生成三个 线程 每 30 秒进行一次转储 dumps
        JAVA_HOME/bin/jstack -l PID > FILENAME
      2. 如果消息处理器的内存用量较高,则生成 堆转储 创建 Deployment
        sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
      3. 使用以下命令重启消息处理器。这应该会降低 CPU 和内存:
        /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
      4. 监控 API 调用以确认问题是否仍然存在。
      5. 请与 Apigee Edge 支持团队联系并提供 线程转储、堆转储和消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log)帮助他们 调查 CPU/内存用量高的原因。

增加超时值, 路由器和消息处理器

谨慎选择要在路由器和消息处理器上设置的超时值,具体取决于 您的要求。请勿将超时值设置得过大。如需帮助,请联系 Apigee Edge 支持

路由器

chown apigee:apigee /opt/apigee/customer/application/router.properties
  1. /opt/apigee/customer/application/router.properties 路由器(如果尚未存在)。
  2. 将以下代码行添加到此文件中:
    conf_load_balancing_load.balancing.driver.proxy.read.timeout=TIME_IN_SECONDS

    例如,如果要将超时值设为 120 秒,则设为 如下:

    conf_load_balancing_load.balancing.driver.proxy.read.timeout=120
  3. 确保此文件归 apigee 所有:
  4. 重启路由器:
    /opt/apigee/apigee-service/bin/apigee-service edge-router restart
    
  5. 如果有多个路由器,请在所有路由器上重复上述步骤。

消息处理器

  1. 在以下设备上创建 /opt/apigee/customer/application/message-processor.properties 文件: 消息处理器计算机(如果尚不存在)。
  2. 将以下代码行添加到此文件中:
    conf_http_HTTPTransport.io.timeout.millis=TIME_IN_MILLISECONDS

    例如,如果要将超时值设为 120 秒,则设为 如下:

    conf_http_HTTPTransport.io.timeout.millis=120000
  3. 确保此文件归 apigee 所有:
    chown apigee:apigee /opt/apigee/customer/application/message-processor.properties
  4. 重启消息处理器:
    /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
  5. 如果您有多个消息处理器,请对所有消息重复上述步骤 处理器。

创意 :按以下顺序设置不同组件的超时值:

客户端超时 >路由器超时 >消息处理器超时 &gt;API 代理中的超时

Edge 处理 API 请求的速度缓慢

如果 Edge 运行速度很慢并且/或者处理 API 请求用时很长,那么您将会收到 504 Gateway Timeout 个错误。

诊断

  1. 在 Edge 界面中跟踪受影响的 API。
  2. 请等待错误发生,或者如果您已进行 API 调用,则进行一些 API 调用 并重现 504 Gateway Timeout 错误。
  3. 请注意,在这种情况下,您可能会在 Trace 中看到成功响应。
    1. 由于消息处理器没有在 指定超时期限(以超时期限最短者为准)。 但是,消息处理器会继续处理请求,并可能会完成 成功。
    2. 此外,HTTPTransport.io.timeout.millis 仅当消息处理器与 HTTP/HTTPS 通信时才会触发消息处理器 后端服务器换言之,如果任何政策(其他 与 ServiceCallout 政策相比)需要很长时间。
  4. 发生错误后,检查最长 已用时间
  5. 检查每个阶段所用的时间,并记下用时最长的阶段 。
  6. 如果您在本服务之外的任何政策中观察到最长耗时 调用程序政策,则表示 Edge 需要很长时间来处理 请求。
  7. 以下界面跟踪记录示例显示了 JavaScript 政策上经过的时间非常长:

  8. 在上例中,您注意到 JavaScript 政策花费的时间过长, 时长约为 245 秒

分辨率

  1. 检查政策是否响应时间过长,以及是否有任何自定义代码 可能需要很长时间才能处理完毕如果存在此类代码, 修复/优化已识别的代码。
  2. 如果没有可能导致处理时间较长的自定义代码,则检查消息 以下处理器的 CPU 或内存使用率较高: <ph type="x-smartling-placeholder">
      </ph>
    1. 如果任何消息处理器的 CPU 使用率较高,则生成三个 线程 每 30 秒进行一次转储 dumps
      JAVA_HOME/bin/jstack -l PID > FILENAME
    2. 如果任何消息处理器的内存用量较高,则生成 堆转储 创建 Deployment
      sudo -u apigee JAVA_HOME/bin/jmap -dump:live,format=b,file=FILENAME PID
    3. 使用以下命令重启消息处理器。这应该会降低 和内存。
      /opt/apigee/apigee-service/bin/apigee-service edge-message-processor restart
    4. 监控 API 调用并确认问题是否仍然存在。
    5. Apigee Edge 支持团队联系并提供会话主题 转储、堆转储和消息处理器日志 (/opt/apigee/var/log/edge-message-processor/logs/system.log)帮助他们 调查 CPU/内存用量高的原因。

使用 API 监控来诊断问题

借助 API Monitoring,您可以快速分离问题领域,以诊断错误、性能和延迟问题及其来源。 例如开发者应用、API 代理、后端目标或 API 平台。

逐步执行示例场景,了解如何使用 API 监控来排查 API 的 5xx 问题。 例如,您可以设置提醒,在 504 状态代码的数量超出特定阈值时收到通知。