概述
在讲解 Istio 的熔断实战之前,我们先来了解一下什么熔断以及为什么需要熔断机制。
从本质上来讲,熔断是一种过载保护的手段,目的是避免服务的级联失败。
那么熔断具体是如何实现的呢?
如上图所示:
- 默认情况下,熔断器的默认状态是关闭的,此时调用服务会得到正常的返回;
- 而随时失败次数的增多,达到提示预设的一个阈值时。熔断器会进入Open状态,此时,再次发送请求时将会直接失败,即快速失败机制;
- 针对Open状态,会设置一个超时时间,超过一定时间后会进入半开状态,并尝试调用一次服务,如果调用成功,熔断器进行 Closed 状态,否则重新回到 Open 状态。
实战
场景描述
在本文中,我们将会为 httpbin 服务添加熔断配置,并通过负载测试工具来触发熔断,测试熔断策略的效果。
通过本文的学习,你将会掌握:
- 在 DestinationRule 中添加熔断策略;
- 熔断的基本概念和为什么需要熔断机制。
StepByStep
添加熔断策略
下面,我们基于 Ingress 一文中创建的 httpbin 服务来进行进一步的实验和演示。
首先,我们需要创建一个 DestinationRule 来配置对应的熔断策略,配置文件名为 httpbin-dr.yaml:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
创建使其生效:
kubectl apply -f ./samples/httpbin/httpbin-dr.yaml -n istio-demo
# destinationrule.networking.istio.io/httpbin created
Ps:关于配置的含义,我们会在后文中进行详细阐述。
测试熔断效果
下面,为了测试熔断的效果,我们需要部署一个客户端工具的Pod来进行验证:
kubectl apply -f ./samples/httpbin/sample-client/fortio-deploy.yaml -n istio-demo
等待 Pod 部署完成后,我们来发送一个请求验证一下是否能够正常访问:
FORTIO_POD=$(kubectl get pods -n istio-demo |grep fortio| awk '{print $1 }')
kubectl exec -it $FORTIO_POD -c fortio -n istio-demo /usr/bin/fortio -- load -curl http://httpbin:8000/get
如上图所示,我们可以看到我们的 httpbin 服务可以正常访问。
下面,我们修改一下请求参数,设置并发数为4,共计发送20次请求:
kubectl exec -it $FORTIO_POD -c fortio -n istio-demo /usr/bin/fortio -- load -c 4 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
观察它的输出结果,其中返回码为200的次数为8次,返回码为503的是12次。其中,503正是被熔断策略所拦截下来了!
如果我们将并发调的更大呢?比如调整为10:
kubectl exec -it $FORTIO_POD -c fortio -n istio-demo /usr/bin/fortio -- load -c 10 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
503共计出现了17次,200仅出现了3次。
可以发现,随时并发的上升,再熔断策略的影响下,真正成功的请求比例会有明显降低,从而保证后端服务接收的压力始终限制在某个阈值之内。
原理说明
配置分析
下面,我们来解读一下刚才配置的含义吧:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
在上述 DestinationRule 中,我们主要配置了 trafficPolicy 策略,其中包含了:
- connectionPool 连接池配置
- tcp 的最大连接数为1
- http 每个连接的最大请求数为1且最多等待请求数为1
- outlierDetection 失败探测
- consecutiveErrors 失败次数,对应熔断机制的失败计数器
- interval 熔断间隔时间
- baseEjectionTime 最小驱逐时间,默认为30s
- maxEjectionPercent 最大可被驱逐的比例
资源配置项
从上图中,我们可以看到关于 TrafficPolicy 的相对完整的配置图。
关于更多详细的配置及其说明,可以参考 Istio 的官方文档。