服务网格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属性字段

字段类型是否必须说明
workloadSelectormap<string, string>通过一个或多个标签,指明限流配置生效的一组特定的Pod或VM。标签搜索的范围限制在资源所在的配置命名空间。更多信息,请参见WorkloadSelector
isGatewaybool配置为true,表示配置作用于网关。默认为false。
configsCircuitBreakerConfig[]熔断配置,可配置多条。

CircuitBreakerConfig属性字段

字段类型是否必须说明
namestring单条熔断配置的名称。
matchCircuitBreakerMatch匹配条件。
breaker_configBreakerConfig接口级熔断配置。

CircuitBreakerMatch属性字段

字段类型是否必须说明
vhostVirtualHostMatchVirtualHost匹配条件。

BreakerConfig属性字段

字段类型是否必须说明
window_sizeDuration统计时间窗口,默认10s,最大不能超过12s。
break_durationDuration熔断时长,默认30s。
slow_request_rtDuration定义慢请求的响应延迟时间,超过该响应时长的请求则被认定为慢请求。
average_request_rtDuration
  • ASM实例版本为1.14以下:是
  • ASM实例版本为1.14及以上:否
定义业务的平均响应时间,例如: 0.010s。
max_slow_requestsuint32最大慢请求次数,必须为整数,例如:1000。超过该次数新的请求会被熔断。
error_percentPercent错误百分比,时间窗口内错误请求(5XX)比例超过该值,则新的请求会被熔断。
min_request_amountuint32最少请求次数,对应error_percent条件,默认为0。为了防止误判定被熔断,可配置请求最少次数。
custom_responseCustomResponse当请求被熔断时,自定义返回内容。

CustomResponse属性字段

字段类型是否必须说明
status_codeint32HTTP响应状态码。
header_to_addmap[string]string自定义响应添加的Headers。
bodystring自定义响应Body内容。

VirtualHostMatch属性字段

字段类型是否必须说明
namestring匹配的VirtuHost名称。
portint匹配的请求端口。
routeRouteMatch匹配的请求接口对应的路由名称。

RouteMatch属性字段

字段类型是否必须说明
name_matchstring
  • 网关:是
  • Sidecar:否
匹配的路由名称,对应VirtualService下的单条路由名称。
header_matchHeaderMatcher[]匹配服务请求的Header,支持配置多个。
重要 使用该字段需ASM实例为1.16及以上版本,且对应的网关实例和Sidecar都为最新版。关于如何升级ASM实例和网关实例,请参见升级ASM实例;关于如何升级Sidecar,请参见升级Sidecar代理

HeaderMatcher属性字段

字段类型是否必须说明
namestringHeader名称。
任选其一regex_matchstring正则表达式匹配。
exact_matchstring精确匹配。
prefix_matchstring前缀匹配,以什么开头进行匹配。
suffix_matchstring后缀匹配,以什么结尾进行匹配。
present_matchbool
  • 配置为true,表示存在Header即可,无需关注Header Value的取值。
  • 配置为false,表示不存在Header。
invert_matchbool
默认为false
  • 配置为true,表示上述匹配结果取反。
  • 配置为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

  1. 使用以下内容,创建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
  2. 执行以下命令,创建ASMCircuitBreaker。
    kubectl apply -f asmcircuitbreaker-test-gw.yaml
  3. 执行以下命令,模拟请求响应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!,说明请求被熔断。
  4. 执行以下命令,访问Bookinfo服务的/productpage接口。
    curl -H 'host: bf2.example.com'  http://${ASM_GATEWAY_IP}/productpage -v
    在Productpage页面返回HTTP 200响应,说明请求未被熔断。