反模式:使用 MaxFailures 设置为非零值的单个目标服务器进行负载平衡

您正在查看 ApigeeApigee Hybrid 文档。
查看 Apigee Edge 文档。

TargetEndpoint 配置定义 Apigee 连接到后端服务或 API 的方式。它发送请求给后端服务/从后端服务接收请求。后端服务可以是 HTTP/HTTPS 或 NodeJS 服务器。

可通过下列方法之一调用 TargetEndpoint 中的后端服务:

  • 指向 HTTP 或 HTTPS 服务器的直接网址
  • TargetServer 配置

同样,您也可以使用 ServiceCallout 政策从 API 代理流调用任何外部服务。此政策支持直接在政策本身或使用 TargetServer 配置来定义 HTTP/HTTPS 目标网址。

TargetServer 配置

TargetServer 配置将 TargetEndpoint 配置或 Service Callout 政策中的具体端点网址分离。TargetServer 通过名称而不是 TargetEndpoint 的网址引用。TargetServer 配置将使用后端服务的主机名、端口号以及任何其他详细信息。

以下是 TargetServer 配置示例:

<TargetServer name="target1">
  <Host>www.mybackendservice.com</Host>
  <Port>80</Port>
  <IsEnabled>true</IsEnabled>
</TargetServer>

TargetServer 允许您对每个环境使用不同的配置。可以使用 LoadBalancer 通过一个或多个已命名 TargetServer 配置 TargetEndpoint/Service Callout 政策。内置的负载均衡支持增强了配置的后端服务器实例中的 API 和故障切换的可用性。

以下是使用 TargetServer 的 TargetEndpoint 配置示例:

<TargetEndpoint name="default">
    <HTTPTargetConnection>>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

MaxFailures

MaxFailures 配置指定目标服务器的请求失败次数上限,超过此次数后应将目标服务器标记为故障并将其从所有后续请求的轮替中移除。

指定了 MaxFailures 的示例配置:

<TargetEndpoint name="default">
    <HTTPTargetConnection>
      <LoadBalancer>
        <Server name="target1"/>
        <Server name="target2"/>
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
    </HTTPTargetConnection>
</TargetEndpoint>

在以上示例中,如果对“target1”发出的五个连续请求均失败,则系统会从轮替中移除“target1”,且仅将所有后续请求都发送到 target2。

反模式

不建议在 TargetEndpoint 或 Service Callout 政策的 LoadBalancer 配置中将单个 TargetServer 的 MaxFailures 设置为非零值,因为这会产生不良影响。

请考虑以下示例配置,其中将一个名为"target1"的单个 TargetServer 的 MaxFailures 设置为 5(非零值):

<TargetEndpoint name="default">
  <HTTPTargetConnection>
      <LoadBalancer>
        <Algorithm>RoundRobin</Algorithm>
        <Server name="target1" />
        <MaxFailures>5</MaxFailures>
      </LoadBalancer>
  </HTTPTargetConnection>

如果对 TargetServer“target1”发出的请求失败 5 次(在 MaxFailures 中指定的数量),则会从轮替中移除 TargetServer。由于没有其他 TargetServer 可供故障切换,因此对具有此配置的 API 代理发出的所有后续请求都将失败,并返回 503 Service Unavailable 错误。

即使 TargetServer“target1”返回至正常状态并且可以发送成功响应,对 API 代理发出的请求仍然会继续返回 503 错误。这是因为 Apigee 不会自动将 TargetServer 重新置于轮替中,即便该目标已重新启动并运行也是如此。如需解决此问题,必须重新部署 API 代理,Apigee 才能将 TargetServer 重新置于轮替中。

如果在 Service Callout 政策中使用相同的配置,则在对 TargetServer“target1”发出的请求失败 5 次后,API 请求就会收到 500 错误。

影响

如果在 TargetEndpoint 或 Service Callout 政策的 LoadBalancer 配置中使用单个 TargetServer,并将 MaxFailures 设置为非零值,会导致:

  • 在重新部署 API 代理之前,API 请求会连续失败并返回 503/500 错误(请求失败次数达到 MaxFailures)。
  • 中断时间较长,因为此过程比较复杂,可能需要更多时间来诊断此问题的原因(未事先了解这种反模式)。

最佳做法

  1. LoadBalancer 配置中有多个 TargetServer,以实现更高的可用性。
  2. MaxFailures 设置为非零值时,务必定义 Health Monitor。当失败次数达到 MaxFailures 中指定的数量时,将从轮替中移除目标服务器。拥有 HealthMonitor 可确保,目标服务器再次可用时就可将 TargetServer 重新置于轮替中,这意味着无需重新部署代理

    如需确保在 Apigee 用于连接到目标服务器的相同端口号执行健康检查,Apigee 建议您忽略 <TCPMonitor> 下方的 <Port> 子元素,除非它与 TargetServer 端口不同。默认情况下,<Port> 与 TargetServer 端口相同。

    使用 HealthMonitor 的示例配置

    <TargetEndpoint name="default">
      <HTTPTargetConnection>
        <LoadBalancer>
          <Algorithm>RoundRobin</Algorithm>
          <Server name="target1" />
          <Server name="target2" />
          <MaxFailures>5</MaxFailures>
        </LoadBalancer>
        <Path>/test</Path>
        <HealthMonitor>
          <IsEnabled>true</IsEnabled>
          <IntervalInSec>5</IntervalInSec>
          <TCPMonitor>
            <ConnectTimeoutInSec>10</ConnectTimeoutInSec>
          </TCPMonitor>
        </HealthMonitor>
      </HTTPTargetConnection>
    </TargetEndpoint>
  3. 如果存在一些限制,以便只有一个 TargetServer,并且未使用 HealthMonitor,则不要在 LoadBalancer 配置中指定 MaxFailures

    MaxFailures 的默认值为 0。 这意味着 Apigee 总是会尝试针对每个请求连接到目标,且绝不会从轮替中移除目标服务器。

更多详情