1.雪崩的概念?

服务启动因为dubbo依赖过多变的很慢_提供方

 【图1】

        目前越来越多公司开始使用微服务的开发模式,在项目中各种rpc服务的调用也是越来越多,随着团队扩建和项目激增,很多时候我们并不能很好的把握全链路的服务抗压能力。一旦在业务链路中的某几个环节出现短暂性故障不可用,而服务请求在用户因服务不可用而重复请求,又或者是dubbo、mq等框架、中间件的重试容错机制下,就有可能导致故障节点的故障被扩散-其他服务的资源被大量用于请求故障资源,严重的将会导致全链路服务的不可用现象出现。最初出现故障的可称为故障源,直接或者间接依赖于故障源的服务可称之为感染节点,故障源一旦是通用性基础服务,这时候感染节点覆盖面会非常大。

        如【图1】 A服务调用B,B调用C,B调用E,A服务同时也调用D,A、服务资源较多,能抗住很多的流量,B、C、D服务次之,当C出现故障全量或者多数资源不可用时,在大量重试情况下会逐步把A B的资源耗尽,首先出现的是A->B->C 链路业务不可用,再者由于A、B不可用,导致A->D,B->E也不可用,最终全链路不可用,当然这是极端情况,目前很多中间件和框架都提供流量很多的高可用保护策略,下面会讲到

2.常见出现的场景?

        1.常见的有缓存的异常导致业务请求直接打到响应时间相对较慢的db层,导致当前节点出现服务超时现象,而服务上下游没有做高可用的保护措施。 比较常见

        2.类似于mq、dubbo类的重试容错机制配置的不合理:

举个例子:dubbo中服务消费方的超时时间远小于提供方超时时间,但是基于前文讲到的dubbo的配置优先级策略,会以服务消费方为主(这是我觉得不太合理的地方),同时该服务消费方又配置了不合理的重试机制或者用户并发相对较高,就会导致大量的服务提供方资源被这个异常的消费方占用,而这个消费方的故障就会通过服务提供方扩散污染其他的消费方。 在大型项目中有可能出现,一旦出现影响会很严重。

3.现有状态线上出现后的应急方案?(这里以dubbo为例)

        1.如果服务配置了服务熔断降级则考虑一下当前服务的业务重要性,配合dubbo控制平台考虑如何启用流控、降级、熔断等措施

        2.如果很不幸没有配置,应快速手动将服务做”硬降级“=下线/流控/转换实现等措施,重新发布,这样存在二次以及连锁bug的风险,所以应在架构设计,服务开发发布前

做好相关服务高可用的规划设计。下面介绍一下在dubbo中针对这个问题的一些解决方案。

4.业内现有的解决方案有哪些?优缺点?适用范围?

        保证系统的稳定性和高可用性,我们需要采取一些高可用策略,目的是构建一个稳定的高可用工程系统,我们一般采用如下方案。

 4-1.服务冗余+动态故障转移策略:

        对于同一个服务起多个相同的应用在某一服务节点发生故障时,按照一定的 均衡负载策略(默认策略:Random LoadBalance随机,按权重设置随机概率)把服务请求打到其他相同的服务节点上去

在dubbo中也就是服务的集群形式部署再加使用failover(默认的)策略

4-1-1.负载均衡配置示例:

<dubbo:service loadbalance="roundrobin" />

4-1-2.failover配置示例:

<dubbo:service interface="xxx" cluster="failover" />

4-2.服务的降级策略:

4-2-1.服务降级:

        当服务器压力剧增的情况下,根据当前业务情况及流量对一些服务有策略的降低服务级别,以释放服务器资源,保证核心任务的正常运行

4-2-2.降级方式:

                a.部分服务暂停

                b.全部服务暂停

                c.随机拒绝服务

                d.部分服务延迟

4-2-3.Dubbo的服务降级采用的是mock机制。其具有两种降级处理方式(一般配合超时机制使用,默认是只要配置了降级,在发生rpc异常都会降级):

               a. Mock Null降级处理,

@DubboReference(check = false,timeout=3000, mock = "return null")

                b. 与Mock Class降级处理。                

@DubboReference(check = false,timeout=3000, mock ="com.blackball.service.mock.UserServiceMock")

** 注意服务降级策略和服务冗余+动态故障转移策略虽然是为了解决服务故障的高可用策略,而且确实可以解决网络抖动产生的服务短暂性不可用故障,但是如何单纯使用着两个策略不配合服务熔断使用会出现,no provider的异常,而且如果是超时问题并且非偶发性的具备较长持续时间的故障,这时候故障还是会在整个系统内部被放大,因为消费者还会进行 1+retires 次的 RPC 调用,这样就更加浪费资源了,所以他们和服务熔断一般配合使用好点**

4-3.服务熔断策略:

        在命中指定的规则后把目标服务置为不可用状态,并配合服务降级来做服务故障转移的平滑处理。

        dubbo中一般在使用服务降级时记得加上熔断机制,不管是业务错误还是请求超时,只要时间内达到了一定的次数/qps等就做上述的熔断处理,待服务状态恢复正常后再将服务恢复,这样就可以防止没有必要的调用。

4-4.常见配合使用的熔断框架有

1.Sentinel:

2.hystrix(豪猪)

两者的区别

(这两个熔断框架原理以及使用不做深入,后续再解析)

5.对于未来的思考?

        1.首先对于dubbo的配置优先级策略-即消费方优先,再吐槽一边,服务消费方配置至上的原则有时候会对服务提供方带来很多意料不到的麻烦,但是这样又同时影响到了其他的服务消费方。

       2.展望:是否可以针对服务消费方做应用级别(业务级别)的区别,服务消费方优先级别不变对于消费方,但是对于服务提供方应当对自身有自我保护措施而且是默认开启的

具体实现思路如下:

        2-1.服务调用方自动记录每次服务调用时的服务消费方的身份(可以通过服务消费方启动时间+ip+应用名等计算唯一键)、参数、是否成功、并记录失败原因、失败次数、rt等消费方对某一个服务使用的健康记录。

        2-2.拿到这些健康记录后就可以做很多事了,设置默认策略(策略不支持扩展,处于对服务提供方的保护),自动对该服务消费方做服务端的定向降级熔断、并发送提醒(定向被动降级日志,可以支持扩展各类提醒接口),这个策略默认开启(其实服务提供方感觉就不该允许关闭这个策略) 

具体代码实现demo下一期上...