服务网格ASM支持通过编写VirtualService和DestinationRule等资源,实现微服务的无侵入的流量治理能力,包括流量路由、限流、熔断、镜像流量等功能。本文介绍如何使用ASM接口级熔断功能。
前提条件
- 已下载本文所需配置文件,具体请参见配置文件。
- 已创建ASM专业版实例,且版本为v1.13.4及以上。具体操作,请参见创建ASM实例。
- 已添加集群到ASM实例。具体操作,请参见添加集群到ASM实例。
- 已部署入口网关服务。具体操作,请参见创建入口网关服务。
- 已创建Bookinfo和Nginx服务。具体操作,请参见部署应用到ASM实例。
- 已通过kubectl连接ASM实例。具体操作,请参见通过控制面kubectl访问Istio资源。
- 已部署网关规则。具体操作,请参见管理网关规则。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: bookinfo-gateway namespace: default spec: selector: istio: ingressgateway servers: - hosts: - bf2.example.com port: name: http number: 80 protocol: http
- 已创建虚拟服务。具体操作,请参见管理虚拟服务。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: bookinfo namespace: default spec: gateways: - bookinfo-gateway hosts: - bf2.example.com http: - match: - uri: exact: /productpage - uri: prefix: /static - uri: exact: /login - uri: exact: /logout - uri: prefix: /api/v1/products name: productpage-route-name1 route: - destination: host: productpage port: number: 9080 - match: - uri: prefix: /httpbin name: httpbin-route-name1 rewrite: uri: / route: - destination: host: httpbin.foo.svc.cluster.local port: number: 80
- 已安装流量加压工具。具体操作,请参见hey。
背景信息
ASM支持在流量策略中配置熔断功能,在网络访问超出熔断配置时能够拒绝请求。在DestinationRule资源中,
TrafficPolicy
字段下有以下两个熔断配置项:ConnectionPoolSettings
:为服务配置连接的数量。例如控制请求的最大数量,挂起请求,重试或者超时。OutlierDetection
:用于从负载均衡池中剔除不健康的实例。
社区Istio提供的DestinationRule熔断配置如下,更多信息,请参见destination-rule。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
社区Istio提供的熔断功能,Envoy通过连接池实现对上游集群的限流熔断,通过周期性的动态异常检测来确定上游集群中的某些主机是否异常。如果发现异常,则将该主机从连接池中隔离出去。这本质上是针对上游主机整体的熔断。有以下两个缺点:
- 仅支持服务级别熔断,不支持某个API进行限流熔断。
- 在路由规则后起作用,无法做到流量分发之前进行限流熔断。
基于以上问题,ASM在数据面Envoy侧进行了Filter链的扩展,通过
com.aliyun.break filter
支持接口级熔断能力,控制面通过CRD: ASMCircuitBreaker
进行用户侧的透出,具体使用说明如下图所示。
本文以Bookinfo和Httpbin为例模拟慢请求和错误请求。其中,Bookinfo部署在default命名空间,Httpbin服务部署在foo命名空间,ingressgateway网关部署在istio-system命名空间,Httpbin单独部署在foo命名空间的测试后端服务,目的是为了验证熔断的开启范围。

ASMCircuitBreaker声明式配置介绍
说明
ASMCircuitBreaker CRD的apiVersion字段说明如下:
- 若ASM实例版本为1.15.3.105及以上,支持使用
apiVersion: istio.alibabacloud.com/v1
。若您在ACK集群进行了相关配置,请将对应的ASMCircuitBreaker CRD中的apiVersion: istio.alibabacloud.com/v1beta1
修改为apiVersion: istio.alibabacloud.com/v1
,再重新进行部署。 - 若ASM实例版本为1.15.3.105以下,支持使用
apiVersion: istio.alibabacloud.com/v1beta1
。
ASM通过CRD ASMCircuitBreaker实现本地限流的声明式配置。配置Spec说明如下:
ASMCircuitBreakerSpec属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
workloadSelector | map<string, string> | 是 | 通过一个或多个标签,指明限流配置生效的一组特定的Pod或VM。标签搜索的范围限制在资源所在的配置命名空间。更多信息,请参见WorkloadSelector。 |
isGateway | bool | 否 | 配置为true,表示配置作用于网关。默认为false。 |
configs | CircuitBreakerConfig[] | 是 | 熔断配置,可配置多条。 |
CircuitBreakerConfig属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
name | string | 否 | 单条熔断配置的名称。 |
match | CircuitBreakerMatch | 否 | 匹配条件。 |
breaker_config | BreakerConfig | 否 | 接口级熔断配置。 |
CircuitBreakerMatch属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
vhost | VirtualHostMatch | 否 | VirtualHost匹配条件。 |
BreakerConfig属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
window_size | Duration | 否 | 统计时间窗口,默认10s,最大不能超过12s。 |
break_duration | Duration | 否 | 熔断时长,默认30s。 |
slow_request_rt | Duration | 否 | 定义慢请求的响应延迟时间,超过该响应时长的请求则被认定为慢请求。 |
average_request_rt | Duration |
| 定义业务的平均响应时间,例如: 0.010s。 |
max_slow_requests | uint32 | 否 | 最大慢请求次数,必须为整数,例如:1000。超过该次数新的请求会被熔断。 |
error_percent | Percent | 否 | 错误百分比,时间窗口内错误请求(5XX)比例超过该值,则新的请求会被熔断。 |
min_request_amount | uint32 | 否 | 最少请求次数,对应error_percent条件,默认为0。为了防止误判定被熔断,可配置请求最少次数。 |
custom_response | CustomResponse | 否 | 当请求被熔断时,自定义返回内容。 |
CustomResponse属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
status_code | int32 | 否 | HTTP响应状态码。 |
header_to_add | map[string]string | 否 | 自定义响应添加的Headers。 |
body | string | 否 | 自定义响应Body内容。 |
VirtualHostMatch属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
name | string | 否 | 匹配的VirtuHost名称。 |
port | int | 否 | 匹配的请求端口。 |
route | RouteMatch | 是 | 匹配的请求接口对应的路由名称。 |
RouteMatch属性字段
字段 | 类型 | 是否必须 | 说明 |
---|---|---|---|
name_match | string |
| 匹配的路由名称,对应VirtualService下的单条路由名称。 |
header_match | HeaderMatcher[] | 否 | 匹配服务请求的Header,支持配置多个。 重要 使用该字段需ASM实例为1.16及以上版本,且对应的网关实例和Sidecar都为最新版。关于如何升级ASM实例和网关实例,请参见升级ASM实例;关于如何升级Sidecar,请参见升级Sidecar代理。 |
HeaderMatcher属性字段
字段 | 类型 | 是否必须 | 说明 | |
---|---|---|---|---|
name | string | 否 | Header名称。 | |
任选其一 | regex_match | string | 否 | 正则表达式匹配。 |
exact_match | string | 否 | 精确匹配。 | |
prefix_match | string | 否 | 前缀匹配,以什么开头进行匹配。 | |
suffix_match | string | 否 | 后缀匹配,以什么结尾进行匹配。 | |
present_match | bool | 否 |
| |
invert_match | bool | 否 | 默认为false。
|
适用场景
ASM接口级熔断功能适用于ASM网关,支持HTTP和GRPC协议。您可以在ASMCircuitBreaker YAML文件中添加istioGateway相关配置,本文以/httpbin
对应路由名称为httpbin-route-name1
配置熔断规则为例进行说明。
apiVersion: istio.alibabacloud.com/v1beta1
kind: ASMCircuitBreaker
metadata:
name: ingressgateway
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
isGateway: true
configs:
- match:
vhost:
name: "bf2.example.com"
port: 80
route:
name_match: nginx-route-name1
breaker_config:
slow_request_rt: 0.1s
break_duration: 90s
window_size: 10s
max_slow_requests: 10
min_request_amount: 3
error_percent:
value: 60
custom_response:
header_to_add:
x-envoy-circuitbreak: "true"
body: "hello, break!"
status_code: 499
部分配置项说明如下:
配置项 | 说明 |
---|---|
isGateway: true | 作用于网关。isGateway 默认为false 。 |
value: 60 | 当请求响应的错误比例超过60%(最少请求3次时),触发熔断。 |
max_slow_requests: 10 | 当慢请求次数超过10次时,触发熔断。 说明 慢请求是指请求响应时间RT(Reaction time)超出 slow_request_rt 定义的请求。 |
break_duration: 90s | 每次熔断的时长定义为90s。 |
配置并验证熔断规则
本文以单个接口配置熔断规则为例,对bf2.example.com:80
这个VirtualHost下的某条路由进行限流配置,路由名称为httpbin-route-name1
。
- 使用以下内容,创建asmcircuitbreaker-test-gw.yaml文件。
apiVersion: istio.alibabacloud.com/v1beta1 kind: ASMCircuitBreaker metadata: name: ingressgateway namespace: istio-system spec: workloadSelector: labels: app: istio-ingressgateway isGateway: true configs: - match: vhost: name: "bf2.example.com" port: 80 route: name_match: httpbin-route-name1 breaker_config: slow_request_rt: 0.1s break_duration: 90s window_size: 10s max_slow_requests: 10 min_request_amount: 3 error_percent: value: 60 custom_response: header_to_add: x-envoy-overload: "true" body: "hello, break!" status_code: 499
- 执行以下命令,创建ASMCircuitBreaker。
kubectl apply -f asmcircuitbreaker-test-gw.yaml
- 执行以下命令,模拟请求响应1s延迟或Httpbin响应500错误(连续请求10次左右)。
- 模拟请求响应1s延迟:
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/httpbin/delay/1 -v
- 模拟Httpbin响应500错误:
curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/httpbin/status/500 -v
预期输出:
由预期输出得到,返回< HTTP/1.1 499 Unknown < Content-Length: 12 < Content-Type: text/plain < x-envoy-overload: true < Date: Thu, 13 Jan 2022 03:03:09 GMT < Server: istio-envoy < Hello,Break!
Hello,Break!
,说明请求被熔断。 - 模拟请求响应1s延迟:
- 执行以下命令,访问Bookinfo服务的
/productpage
接口。curl -H 'host: bf2.example.com' http://${ASM_GATEWAY_IP}/productpage -v
在Productpage页面返回HTTP 200
响应,说明请求未被熔断。