分布式系统存在高度复杂性的特点,在基础设施、应用逻辑、运维流程等环节都可能存在稳定性风险而导致业务系统的失效。因此构建一个具有容错能力的分布式系统非常重要。本文介绍如何通过ASM设置超时、重试、隔板和熔断机制构建分布式系统的容错能力。
背景信息
容错能力是指系统在部分故障期间,仍然能够继续运行的能力。创建一个可靠的弹性系统会对其中的所有服务提出容错要求。云环境的动态性质要求服务能预见这些失败,并能优雅地响应意外情况。
任何一个服务都有可能存在请求失败的情况,在请求失败的情况下,能够使用适当的后备操作非常重要。一个服务中断可能会引起连锁反应从而导致严重的业务后果,因此构建、运行和测试系统的弹性能力非常必要。ASM提供了超时处理、重试机制、隔板模式和熔断机制容错解决方案,在不修改应用程序任何代码的情况下为应用程序带来了容错能力。
超时处理
原理介绍
当请求上游服务的时候,存在上游服务一直没有响应的现象。您可以设置一个等待时间,到达一个等待时间后,如果上游服务还是没有响应,直接请求失败,不再去等待上游服务。
通过设置超时,可以确保应用程序在后端服务无响应时可以收到错误返回,从而使其能够以适当的回退行为进行处理。超时更改的是发出请求的客户端等待响应的时间,对目标服务的处理行为没有影响。因此这并不意味着请求的操作失败。
解决方案
ASM支持在虚拟服务中为路由设置超时策略来更改超时值,如果Sidecar代理在设置的时间内未收到响应,则该请求将失败。通过这种方式调整超时,所有使用路由的请求都将使用该超时设置。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- 'httpbin'
http:
- route:
- destination:
host: httpbin
timeout: 5s
timeout:设置超时时间,如果在设置的时间内请求的服务没有响应,则直接返回错误结果,不再等待。
重试机制
原理介绍
解决方案
ASM支持使用虚拟服务定义HTTP请求重试策略。以下示例定义网格中的服务请求httpbin应用时,如果httpbin应用无响应或与httpbin应用建立连接失败,会重新请求httpbin应用3次,每次的请求时间为5秒。apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- 'httpbin'
http:
- route:
- destination:
host: httpbin
retries:
attempts: 3
perTryTimeout: 5s
retryOn: connect-failure,reset
您可以在retries结构中配置如下字段,自定义Sidecar对请求进行重试的行为。
字段 | 说明 |
---|---|
attempts | 一个请求的最大重试次数。如果在配置重试机制的同时,为服务路由配置了超时时间,则实际的重试次数取决于超时时间的设置。例如,如果一次请求未达到最大重试次数,但所有重试花费的总时间已经超过了超时时间,则Sidecar代理会停止请求重试并进行超时返回。 |
perTryTimeout | 每次重试的超时时间,单位为毫秒(ms)、秒(s)、分钟(m)或小时(h)。 |
retryOn | 指定在何种条件下进行重试。多个重试条件需使用英文半角逗号(,)分隔。更多信息,请参见常见的HTTP请求重试条件和常见的gRPC请求重试条件。 |
重试条件 | 说明 |
---|---|
connect-failure | 如果由于与上游服务建立连接失败(连接超时等)导致请求失败,进行重试。 |
refused-stream | 如果上游服务返回REFUSED_STREAM帧来重置流,进行重试。 |
reset | 如果上游服务未响应就发生了连接断开、重置、读取超时事件,进行重试。 |
5xx | 如果上游服务返回任何5XX的响应码(例如500、503等),或上游服务无响应,进行重试。 说明 5XX包含connect-failure和refused-stream的条件。 |
gateway-error | 当上游服务返回502、503或504状态码时,进行重试。 |
envoy-ratelimited | 当请求中存在x-envoy-ratelimited Header时,将进行重试。 |
retriable-4xx | 当上游服务返回409状态码时,进行重试。 |
retriable-status-codes | 当上游服务返回的状态码被判定为可以重试时,进行重试。 说明 您可以直接在retryOn字段中加入合法的状态码,这些状态码将被判定为可以重试的状态码。例如 403,404,retriable-status-codes 。 |
retriable-headers | 当上游服务返回的响应Header中包含可以重试的Header时,进行重试。 说明 您可以在发往上游服务的请求中加入 x-envoy-retriable-header-names Header,以指定哪些响应Header可以重试。例如,在请求Header中加入x-envoy-retriable-header-names: X-Upstream-Retry,X-Try-Again 。 |
重试条件 | 说明 |
---|---|
cancelled | 如果上游gRPC服务的响应头部中的gRPC状态码为cancelled(1),进行重试。 |
unavailable | 如果上游gRPC服务的响应头部中的gRPC状态码为unavailable(14),进行重试。 |
deadline-exceeded | 如果上游gRPC服务的响应头部中的gRPC状态码为deadline-exceeded(4),进行重试。 |
internal | 如果上游gRPC服务的响应头部中的gRPC状态码为internal(13),进行重试。 |
resource-exhausted | 如果上游gRPC服务的响应头部中的gRPC状态码为resource-exhausted(8),进行重试。 |
配置默认HTTP请求重试策略
- 登录ASM控制台,在左侧导航栏,选择 。
- 在网格管理页面,单击目标实例名称,然后在左侧导航栏,选择 。
- 在基本信息页面的配置信息区域,单击默认HTTP请求重试策略右侧的编辑。
- 在默认HTTP请求重试策略对话框,配置相关信息,然后单击确定。
配置项 说明 重试次数 对应上文的attempts。在默认HTTP请求重试策略中,该字段可以配置为0,表示默认禁用HTTP请求重试。 重试超时 对应上文的perTryTimeout。 重试条件 对应上文的retryOn。
隔板模式
原理介绍

解决方案
ASM支持通过目标规则设置隔板模式,以下目标规则定义了其他服务请求httpbin应用时,最大并发连接数限制为1,每个连接最大请求数为1,最大请求重试次数为1,并且不能在10秒内建立连接的服务会得到503响应。
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
- http1MaxPendingRequests:最大请求重试次数。
- maxRequestsPerConnection:每个连接最大请求数。
- connectTimeout:连接超时时间。
- maxConnections:最大连接数。
熔断机制
原理介绍

解决方案
ASM支持通过目标规则设置熔断机制,以下目标规则定义了如果其他服务请求httpbin应用时,在5秒内连续3次访问失败,则将在5分钟内断开请求。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
outlierDetection:
consecutiveErrors: 3
interval: 5s
baseEjectionTime: 5m
maxEjectionPercent: 100
- consecutiveErrors:连续错误数量。
- interval:移除检测的时间间隔。
- baseEjectionTime:最小的移除时间长度。
- maxEjectionPercent:负载均衡池中允许被移除的主机的最大百分比。