使用服务网格构建分布式系统中的容错能力

服务网格本质上是存在于服务之间的网络,为微服务带来了弹性,。通过一种轻量级的Sidecar模式负责管理服务之间的流量, 可用于部署具有弹性的微服务。
容错能力是指系统在部分故障期间, 仍然能够继续运行的能力。创建一个可靠的弹性系统会对其中的所有服务提出容错要求。云环境的动态性质要求编写的服务能预见这些失败, 并能优雅地响应意外情况。服务网格在不要求应用程序修改任何代码的情况下为应用程序带来了容错能力。

在分布式系统架构下, 必须考虑面向失败的设计。 任何一个服务都必须假定远程调用可能失败,并且必须使用适当的后备操作进行准备。一个服务中断可能会引起连锁反应从而导致严重的业务后果,因此我们构建、运行和测试系统的弹性能力非常必要。

使用服务网格技术构建的容错解决方案通常着重于以下几个方面:

  • 超时处理(timeouts)
  • 隔板模式(bulkheads)
  • 回退机制(fallbacks)
  • 熔断机制(circuit breakers)

超时处理

防止故障的第一道防线就是使用超时机制。通过设置超时, 可以确保应用程序在后端服务无响应时可以收到错误返回,从而使其能够以适当的回退行为进行处理。超时更改的是发出请求的客户端等待响应的时间, 它们对目标服务的处理行为没有影响,因此这并不意味着请求的操作失败。

服务网格ASM支持在VirtualService定义中为路由设置超时策略来更改超时值,如果sidecar代理在设置值时间内未收到响应,则该请求将失败。

该策略如下所示:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - 'httpbin'
  http:
  - route:
    - destination:
        host: httpbin
    timeout: 5s

通过这种方式调整超时,所有使用路由的请求都将使用该超时设置。

隔板模式

隔板模式有助于隔离用于服务的资源,并避免级联故障。通过以下使用DestinationRule来限制上游服务的连接池,从而定义服务间隔板。 其中,最大连接数和连接超时时间是对 TCP 和 HTTP 都有效的通用连接设置; 而每个连接最大请求数和最大请求重试次数仅针对 HTTP1.1/HTTP2/GRPC 协议的连接生效。
使用服务网格构建分布式系统中的容错能力

示例如下:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
      tcp:
        connectTimeout: 10s
        maxConnections: 1

此配置将与示例服务的每个实例建立的最大并发连接数限制为1, 并且不能在10秒内建立连接的服务会得到503 -- Service Unavailable 响应。

重试机制

在微服务弹性设计架构中,假设请求某个服务节点时遭遇请求失败,例如请求超时、连接超时、服务宕机等一系列可能的错误,这时可以通过配置重试机制,重新请求其他服务。

重试请求虽然是最简单的回退机制, 但重试请求可能会导致级联的系统故障, 也就是常说的重试风暴。不要过于频繁地重试或重试过长时间。 在短时间内重试不太可能成功,因为服务可能还未恢复。 此外,如果在服务尝试恢复时进行了大量连接尝试,则其可能会承受更大压力,并且反复的连接尝试甚至可能使服务不堪重负,导致潜在问题变得更加严重。

服务网格技术可以更有效地执行重试。它已经直接参与请求路由,并且为重试策略提供了与语言无关的一致实现。例如,可以定义一个类似于以下示例的策略:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
  - 'httpbin'
  http:
  - route:
    - destination:
        host: httpbin
    retries:
      attempts: 3
      perTryTimeout: 5s

通过这种简单的配置,通过Sidecar代理或入口网关对后端服务的请求最多可以重试3次,每次尝试都将有5秒钟的超时时间。Sidecar确定重试之间的间隔,并在两次尝试之间故意引入抖动,以避免轰炸过载的服务。

熔断机制

发生故障时,熔断器用于优化出站请求的行为。熔断器不会重复向无响应的服务发出请求,而是观察在给定时间段内发生的故障数。如果错误率超过阈值,则熔断器将断开请求,并且所有后续请求都将失败,直到熔断器被关闭为止。
使用服务网格构建分布式系统中的容错能力

异常检测OutlierDetection是服务网格中的熔断实现,用于跟踪上游服务中每个主机的状态,支持HTTP和TCP类型的服务。对于HTTP服务来说,在预定义的时间段内,持续返回API调用的5xx错误的主机将在连接池中被移除。对于TCP服务来说,连接超时或连接失败将被认为异常。

熔断器通过使用DestinationRule定义:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    outlierDetection:
      consecutiveErrors: 3
      interval: 5s
      baseEjectionTime: 5m
      maxEjectionPercent: 100

指定的outlierDetection流量策略将应用于每个单独的实例, 摘除在5秒钟内连续三次失败的服务实例, 并保持摘除至少5分钟。可以摘除所有实例, 即比例为100%。maxEjectionPercent设置与负载平衡有关。服务网格会维护负载均衡池,并从该池中摘除失败的实例。默认情况下,它会从负载平衡池中弹出最多10%的所有可用实例。

阿里云服务网格(简称ASM)是一个统一管理微服务应用流量、兼容Istio的托管式平台。通过流量控制、网格观测以及服务间通信安全等功能,服务网格ASM可以全方位地简化您的服务治理,并为运行在异构计算基础设施上的服务提供统一的管理能力,适用于ACK Kubernetes集群、ASK Serverless Kubernetes集群、边缘集群、ECS虚拟机以及自建Kubernetes集群。
具体参见:https://www.aliyun.com/product/servicemesh

上一篇:PHP直播源码,实现简单弹幕效果


下一篇:Service Mesh 最火项目 Istio 架构解析