服务具备弹性是指系统能够优雅地处理故障并从故障中恢复。尽管我们在进行服务设计时会尽量做高可用方案,但是服务出现故障或者服务间通信的网络出现故障的情况是无法避免的,当故障出现时,我们应该尽量保证服务的可用性,不要让故障变得更加严重,影响整个应用的稳定性。
Istio提供了许多开箱即用的提升服务弹性的功能,包括负载均衡、连接池、健康检测、熔断、超时、重试、限流,这些功能都是服务治理的必备功能。通过组合使用这些功能,可以让服务更具弹性。
·负载均衡 。当服务有多个实例时,通过负载均衡器来分发请求,负载均衡器一般会提供轮询、随机、最少连接、哈希等算法。
·连接池 。当服务调用上游服务时,可以提前创建好到上游服务的连接,当请求到来时,通过已经创建好的连接直接发送请求给上游服务,减少连接的创建时间,从而降低请求的整体耗时。我们把这些提前创建好的连接集合称为连接池。
·健康检测 。当上游服务部分实例出现故障时,健康检测机制能自动检测到上游服务的不可用实例,从而避免把请求发送给上游不可用的服务实例。
·限流 。当服务并发请求激增,流量增大,如果没有使用任何限流措施,这很有可能导致我们的服务无法承受如此之多的请求,进而导致服务崩溃,还可能会影响整个应用的稳定性。限流功能是当请求数过多时,直接丢掉过多的流量,防止服务被压垮,保证服务稳定。
·超时 。当上游服务响应时间过长,很有可能会增加请求的整体耗时,影响服务调用方。通过设置服务调用的超时时间,当服务没有在规定的时间内返回数据,就直接取消此次请求,这样可以防止服务提供方拖垮服务调用方,防止请求的总耗时时间过长。
·重试 。网络出现抖动,或者被调用的服务出现瞬时故障,这些问题都是偶发瞬时的,只需要再重新调用一次后端服务,可能请求就会成功。这种场景下就需要服务的重试功能,防止由于被调用方的服务偶发瞬时故障,导致出现服务调用不可用的情况,从而影响应用的整体稳定性与可用性。
·熔断 。后端服务调用偶尔出现失败是正常情况,但是当对后端服务的调用出现大比例的调用失败,此时可能由于后端服务已经无法承受当前压力,如果我们还是继续调用后端服务,不仅不能得到响应,还有可能会把后端服务整个压垮。所以当服务出现大比例调用失败时,应停止调用后端服务,经过短暂时间间隔后,再尝试让部分请求调用后端服务,如果服务返回正常,我们就可以让更多的请求调用后端服务,直到服务恢复为正常情况。如果仍然出现无法响应的情况,我们将再次停止调用服务,这种处理后端服务调用的机制就称为熔断。
虽然一个服务出现故障的概率可能很低,但是当服务数量变多,低概率的故障事件就会必然发生。当服务数量持续增长,服务间的调用关系复杂,如果不做服务故障处理,提升服务的弹性,就很有可能因为一个服务的故障导致其他服务也出现故障,进而导致服务出现级联故障,甚至可能导致整个应用出现不可用的现象。这会严重影响我们的应用拆分为微服务后的服务可用性指标,使整个应用的用户体验变差,导致用户流失,进而影响业务发展。如果经常出现这种故障,这对业务来说无疑是毁灭性的打击。
【实验前的准备】
进行本章实验前,需要先执行如下的前置步骤。
1)下载实验时用到的源码仓库:
$ sudo yum install -y git $ git clone https://github.com/mgxian/istio-lab Cloning into 'istio-lab'... remote: Enumerating objects: 252, done. remote: Counting objects: 100% (252/252), done. remote: Compressing objects: 100% (177/177), done. remote: Total 779 (delta 157), reused 166 (delta 74), pack-reused 527 Receiving objects: 100% (779/779), 283.37 KiB | 243.00 KiB/s, done. Resolving deltas: 100% (451/451), done. $ cd istio-lab
2)开启default命名空间的自动注入功能:
$ kubectl label namespace default istio-injection=enabled namespace/default labeled
3)部署用于测试的服务:
$ kubectl apply -f service/go/service-go.yaml $ kubectl get pod NAME READY STATUS RESTARTS AGE service-go-v1-7cc5c6f574-lrp2h 2/2 Running 0 76s service-go-v2-7656dcc478-svn5c 2/2 Running 0 76s