做者:Laszlo Bence Nagygit
译者:马若飞github
审校:罗广明web
原文:https://banzaicloud.com/blog/istio-circuit-breaking/json
做者简要介绍了熔断的概念,而后以实战演练的方式分别演示了如何经过Backyards UI、CLI等方式建立并设置熔断功能。注:Backyards是Banzai Cloud开发的一款基于Istio的服务网格产品,本文是该产品功能介绍系列中的一篇。后端
Istio因灵活的可观察性和安全的服务间通讯受到了赞许。然而,其余更重要的功能才真正使得Istio成为了服务网格里的瑞士军刀,当遇到运行时长、延迟和错误率等SLO问题时,服务间的流量管理能力是相当重要的。api
在今年早些时候发布 Istio operator 时,咱们的目标(除了管理Istio的安装和升级)是为这些出色的流量路由特性提供支持,同时使全部的功能都更加易用。最后,咱们建立了一个简单且自动化的服务网格Backyards,它在Istio operator之上提供了管理UI、CLI 和GraphQL API的能力。Backyards集成到了Banzai Cloud的容器管理平台 Pipeline中,也能够做为一个单一的产品独立工做。固然,将Backyards与Pipeline一块儿使用会为用户提供特别的好处(好比在多云和混合云环境中管理应用程序),Backyards也能够被用于任何Kubernetes的安装环境。安全
咱们已经发布了一些Backyards相关特性的文章好比:架构
- 流量切换app
在微服务架构中,服务可能会用不一样的语言实现并部署在多个节点或集群上,具备不一样的响应时间或故障率。若是服务成功(而且及时地)响应了请求,那么它的性能就算是使人满意的。但现实状况并不是如此,下游客户端应该在上游服务过于缓慢时受到保护。反之,上游服务也必须被保护,以避免被积压的请求拖垮。在多客户端下状况会更加复杂,并可能致使整个基础设施出现一系列的连锁故障。这一问题的解决方案是采用通过时间检验的熔断器模式。
一个熔断器能够有三种状态:关闭、打开和半开,默认状况下处于关闭状态。在关闭状态下,不管请求成功或失败,到达预先设定的故障数量阈值前,都不会触发熔断。而当达到阈值时,熔断器就会打开。当调用处于打开状态的服务时,熔断器将断开请求,这意味着它会直接返回一个错误,而不去执行调用。经过在客户端断开下游请求的方式,能够在生产环境中防止级联故障的发生。在通过事先配置的超时时长后,熔断器进入半开状态,这种状态下故障服务有时间从其中断的行为中恢复。若是请求在这种状态下继续失败,则熔断器将再次打开并继续阻断请求。不然熔断器将关闭,服务将被容许再次处理请求。
Istio的 熔断 能够在 流量策略 中配置。Istio的 自定义资源Destination Rule
里,TrafficPolicy
字段下有两个和熔断相关的配置: ConnectionPoolSettings 和 OutlierDetection。
ConnectionPoolSettings
能够为服务配置链接的数量。OutlierDetection
用来控制从负载均衡池中剔除不健康的实例。
例如,ConnectionPoolSettings
控制请求的最大数量,挂起请求,重试或者超时;OutlierDetection
设置服务被从链接池剔除时发生错误的请求数,能够设置最小逐出时间和最大逐出百分比。有关完整的字段列表,请参考文档.
Istio在底层使用了Envoy的熔断特性。
让咱们来看看Destination Rule
中有关熔断的配置:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notifications
spec:
host: notifications
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100复制代码
使用ConnectionPoolSettings
字段中的这些设置,在给定的时间内只能和notifications
服务创建一个链接:每一个链接最多只能有一个挂起的请求。若是达到阈值,熔断器将开始阻断请求。
OutlierDetection
部分的设置用来检查每秒调用服务是否有错误发生。若是有,则将服务从负载均衡池中逐出至少三分钟(100%最大弹出百分比表示,若是须要,全部的服务实例均可以同时被逐出)。
在手动建立
Destination Rule
资源时有一件事须要特别注意,那就是是否为该服务启用了mTLS。若是是的话,还须要在Destination Rule
中设置以下字段,不然当调用movies
服务时,调用方可能会收到503错误:
trafficPolicy:
tls:
mode: ISTIO_MUTUAL复制代码
还能够为特定namespace 或特定服务启用全局的mTLS。你应该了解这些设置以便肯定是否把
trafficPolicy.tls.mode
设置为ISTIO_MUTUAL
。更重要的是,当你试图配置一个彻底不一样的功能(例如熔断)时,很容易忘记设置此字段。提示:在建立
Destination Rule
前老是考虑mTLS!
为了触发熔断,让咱们同时从两个链接来调用 notifications
服务。maxConnections
字段被设置为1。这时应该会看到503与200的响应同时到达。
当一个服务从客户端接收到的负载大于它所能处理的负载(如熔断器中配置的那样),它会在调用以前返回503错误。这是防止错误级联的一种方法。
在生产环境中必需要监控你的服务,以便获得通知并可以在系统发生错误时进行检查。所以,若是你已经为你的服务配置了一个熔断器,你就会想知道它何时跳闸;熔断器拦截了百分之多少的请求;什么时候触发,来自哪一个下游客户端?若是可以回答这些问题,你就能够肯定熔断器是否工做正常,并根据须要微调配置,或者优化服务来处理额外的并发请求。
提示:若是你继续阅读,能够在Backyards UI中看到和配置全部的这些设置。
让咱们看看怎样在Istio里肯定熔断器跳闸:
熔断器跳闸时的响应码是503,所以你没法仅根据该响应与其余的503错误区分开来。在Envoy中,有一个计数器叫upstream_rq_pending_overflow
,它记录了熔断且失败的请求总数。若是为你的服务深刻研究Envoy的统计数据就能够得到这些信息,但这并不容易。
除了响应代码,Envoy还返回响应标志 ,而且存在一个专用响应标志来表示熔断器跳闸:UO。若是这个标志只能经过Envoy的日志得到,这将不会特别有用。幸运的是,它在Istio中实现了,所以响应标志在Istio指标中是可用的而且能被Prometheus获取到。
熔断器的跳闸能够像这样查询到:
sum(istio_requests_total{response_code="503", response_flags="UO"}) by (source_workload, destination_workload, response_code)复制代码
使用Backyards时,你不须要手动编辑Destination Rules
来设置熔断。能够经过一个方便的UI界面或者(若是你愿意的话)是Backyards CLI 命令行工具来达到相同的结果。
没必要担忧因为忘记把trafficPolicy.tls.mode
设置为 ISTIO_MUTUAL
而配错了Destination Rules
。Backyards会为你解决这个问题;它会找到启用了mTLS的服务并相应地设置上述字段。
上面只是Backyards验证特性的一个例子,这能避免你设置错误。后面还有更多的特性。
在此之上,你能够看到服务和请求的可视化界面和活动仪表板,所以能够轻松地肯定有多少请求被熔断器触发,以及它来自哪一个调用者和什么时候触发。
首先,咱们须要一个Kubernetes集群。
我经过Pipeline platform的免费开发版本在GKE上建立了一个Kubernetes集群。若是你也想这样作,能够在咱们支持的五个云提供商或使用Pipeline在本地建立集群。不然,你须要提供本身的Kubernetes集群。
在一个新集群安装Istio,Backyards和demo应用的最简单的办法是使用Backyards CLI。
你只须要执行下面的命令(集群必须设置了KUBECONFIG
):
$ backyards install -a --run-demo复制代码
该命令首先使用咱们开源的Istio operator安装Istio,而后安装Backyards和demo应用程序。安装完成后,Backyards UI将自动打开并向demo应用发送一些流量。经过这个简单的命令,你能够看到Backyards在几分钟内启动了一个全新的Istio集群!试试吧!
你也能够按顺序执行全部这些步骤。Backyards须要一个Istio集群——若是没有,能够经过
$ backyards istio install
安装。一旦安装了Istio,就可使用$ backyards install
安装Backyards。最后,使用$ backyards demoapp install
部署demo应用程序。
你不须要手动建立或编辑Destination Rule
,能够很容易的在UI界面中改变熔断的配置。让咱们先建立一个demo。
正如你将看到的,Backyards(与Kiali相比)不只是为可观察性构建的web UI,并且是具备丰富功能的服务网格管理工具,支持单集群和多集群,而且具备强大的CLI和GraphQL API。
你不须要经过Destination Rule
(例如经过kubectl)来查看熔断器的配置,当你点击notification
服务图标并切换SHOW CONFIGS
滑块时,能够在Backyards UI的右侧看到它们。
根据刚才的设置,当两个链接同时产生流量时,熔断器将发出跳闸请求。在Backyards UI中,你将看到图形的边缘出现了红色。若是单击该服务,你将了解有关错误的更多信息,并将看到两个专门用来显示熔断器跳闸的实时Grafana仪表板。
第一个仪表板展现了熔断器触发的总请求的百分比。当没有熔断器错误,而你的服务工做正常,这张图将显示0%
。不然,你将可以当即看到有多少请求被熔断器触发。
第二个仪表板提供了由源熔断器引发的跳闸故障。若是没有发生跳闸,则此图中不会出现尖峰。不然,你将看到哪一个服务致使了跳闸,什么时候跳闸,以及跳闸次数。能够经过此图来追踪恶意的客户端。
这些是实时的Grafana仪表盘,用于显示熔断相关的信息。在默认状况下Backyards集成了Grafana和Prometheus——还有更多的仪表板能够帮助你深刻查看服务的指标。
能够经过 Remove
按钮很容易的移除熔断配置。
这个视频总结了全部这些UI操做(译者注:视频来自YouTube)
从经验来看,能够从UI界面作的事必定也能够经过 Backyards CLI 命令行工具完成。
让咱们再作一次建立熔断的测试,此次经过CLI命令行。
能够以交互模式进行:
$ backyards r cb set backyards-demo/notifications
? Maximum number of HTTP1/TCP connections 1
? TCP connection timeout 3s
? Maximum number of pending HTTP requests 1
? Maximum number of requests 1024
? Maximum number of requests per connection 1
? Maximum number of retries 1024
? Number of errors before a host is ejected 1
? Time interval between ejection sweep analysis 1s
? Minimum ejection duration 3m
? Maximum ejection percentage 100
INFO[0043] circuit breaker rules successfully applied to 'backyards-demo/notifications'
Connections Timeout Pending Requests Requests RPC Retries Errors Interval Ejection time percentage
1 3s 1 1024 1 1024 1 1s 3m 100复制代码
或者用非交互模式,指定要设置的值:
$ backyards r cb set backyards-demo/notifications --non-interactive --max-connections=1 --max-pending-requests=1 --max-requests-per-connection=1 --consecutiveErrors=1 --interval=1s --baseEjectionTime=3m --maxEjectionPercent=100
Connections Timeout Pending Requests Requests RPC Retries Errors Interval Ejection time percentage
1 3s 1 1024 1 1024 5 1s 3m 100复制代码
命令执行后,熔断配置会马上获取到并显示出来。
你能够用下面的命令经过namespace来列出熔断的设置:
$ backyards r cb get backyards-demo/notifications
Connections Timeout Pending Requests Requests RPC Retries Errors Interval Ejection time percentage
1 3s 1 1024 1 1024 5 1s 3m 100复制代码
默认状况结果以表格的方式显示,也支持JSON或者YMAL格式:
$ backyards r cb get backyards-demo/notifications -o json
{
"maxConnections": 1,
"connectTimeout": "3s",
"http1MaxPendingRequests": 1,
"http2MaxRequests": 1024,
"maxRequestsPerConnection": 1,
"maxRetries": 1024,
"consecutiveErrors": 5,
"interval": "1s",
"baseEjectionTime": "3m",
"maxEjectionPercent": 100
}
$ backyards r cb get backyards-demo/notifications -o yaml
maxConnections: 1
connectTimeout: 3s
http1MaxPendingRequests: 1
http2MaxRequests: 1024
maxRequestsPerConnection: 1
maxRetries: 1024
consecutiveErrors: 5
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100复制代码
要从CLI中查看和前面Grafana UI界面相似的仪表板,能够经过从多个链接调用服务来触发跳闸,执行命令:
$ backyards r cb graph backyards-demo/notifications复制代码
能够看到相似下面的结果:
移除熔断执行下面的命令:
$ backyards r cb delete backyards-demo/notifications
INFO[0000] current settings
Connections Timeout Pending Requests Requests RPC Retries Errors Interval Ejection time percentage
1 3s 1 1024 1 1024 5 1s 3m 100
? Do you want to DELETE the circuit breaker rules? Yes
INFO[0008] circuit breaker rules set to backyards-demo/notifications successfully deleted复制代码
使用下面的命令验证是否成功:
$ backyards r cb get backyards-demo/notifications
INFO[0001] no circuit breaker rules set for backyards-demo/notifications复制代码
Backyards由多个组件组成,好比Istio、Banzai Cloud的Istio operator,多集群Canary release operator,以及多个后端基础设施。全部的这些都在Backyards’ GraphQL API的后面。
Backyards UI和CLI都使用Backyards的GraphQL API,它将在9月底与GA版本一块儿发布。用户将很快可以使用咱们的工具来管理Istio和构建他们本身的客户端。
从你的集群移除demo应用、Backyards和Istio,执行下面的命令,它将按顺序卸载这些组件:
$ backyards uninstall -a复制代码
使用Backyards,你能够经过UI或CLI命令行工具轻松的配置熔断器。而后经过嵌入的Grafana仪表板从Backyards UI实时的监控熔断器,来查看跳闸率和按源计算的跳闸次数。
下一次咱们将介绍错误注入,请继续关注!
ServiceMesher 社区是由一群拥有相同价值观和理念的志愿者们共同发起,于 2018 年 4 月正式成立。
社区关注领域有:容器、微服务、Service Mesh、Serverless,拥抱开源和云原生,致力于推进 Service Mesh 在中国的蓬勃发展。
社区官网:https://www.servicemesher.com