开发者学堂课程【服务发现与配置管理高可用最佳实践:服务发现与配置管理高可用最佳实践】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/968/detail/14889
服务发现与配置管理高可用最佳实践
内容介绍
一、案例
二、微服务高可用设计
三、服务发现高可用
四、配置管理高可用
五、实践
一、案例
有一个客户在阿里云上,使用 K8S 集群去部署自己的微服务,但是在某一天的其中一个节点网卡发生异常。最终导致有些服务不可用,无法调用下游,业务受损。
1.原因:
(1)在这个节点上,运行的是 K8S 集群的核心的技术组件 CoreDNS 中所有的pod,俩个pod都在上面,pod没有被打散原因是:最早创建这个集群的时候,只有一个节点,随着一个节点的情况下,这个核心组件的所有 pod 就只能部署在这个节点之上。
(2)后来K8S扩容 node时,如果没有做任何的升级变更( CoreDNS 的pod没有迁移到新的 node上),就始终会留在这个节点。
(3)客户使用了有缺陷的客户端版本,nacos-client-1.4.1 版本的客户端有个跟 DNS 有关的缺陷(短暂域名解析失败时会导致与服务端心跳永久丢失),在心跳请求失败时,会导致异常,最终实例不再续约心跳,直至重启 NacosClient 所在的 pod 后才逐步恢复。
(4)阿里云在5月份推送 nacos-client-1.4.1 存在严重 bug 的公告给用户。客户研发的时间比较晚,在公告之后,没有注意到这样公告,最后将版本应用到了生产环境中。
风险是环环相扣的,缺一不可。
2.导致服务无法调用下游,业务受损的原因
(1)假设下游 provider 的心跳,在 DNS 发生异常时,这个异常在客户端 nacos-client-1.4.1客户端没有正确地去处理异常。
(2)异常没有 catch 住线程(心跳的线程退出),心跳没有再续到注册中心。
(3)注册中心的正常机制是如果心跳没有续约,在30秒之后自动下线。
(4)由于 CoreDNS 在整个 K8S 开发的集群里,负责所有的DNS前期,所有的provider的实例都遇到相同的问题,所以整个服务里所有的实例都被自动下线。在 consumer 收到了注册中心推送给空列表之后,他就开始报无法找到下游的异常。
它的上游,例如:从网关过来的请求,就会直接报错,最终导致业务不可用,整个系统可用性降低。
推送的升级通知:
nacos-client 14.1 在使用域名模式连接服务端时。会存在比较严重的 bug。描述如下:当使用域名模式连接 Nacos 时。
客户端与 Nacos Server 如果发生短暂的域名解析问题,会导致心跳永久丢失。进而引发服务全量下线的问题;即使网络恢复。也不会自动恢复心跳。
域名解析失败常见于网络抖动或者 K8s 环境下的 coreDNS 访问超时等场景,为避免域名解析对 Nacos 造成的重大影响,请务必自查应用代码中使用的 nacos-client 的版本。
修复方案:该问题仅存在于14.1版本,低于此版本不受此问题的影响,使用1.4.1的用户建议升级至1.4.2以避免此问题。使用Spring Clloud/Dubbo 的用户,需要确认实际框架使用的 nacos-client 版本,可以通过显示指定 nacos-client 的版本以覆盖框架默试的版本。
3.在每一环,看起来发生的概率很小,但是一旦发生,就会造成恶劣的影响。
二、微服务高可用设计
没有任何系统是100%没有问题的,高可用架构就是面对失败(风险)设计。风险发生概率虽小,但无法避免。
1.微服务系统中可能的风险:
(1)基础设施:计算存储破坏(自然灾害);物理链路中断(光缆、电力等)
(2)操作系统依赖:存储故障(内存、磁盘);网络抖动(丢包、高延迟);内核 Bug (IOHang) ;时间不对齐(影响验签、协议等) ;DNS 无法解析
(3)服务端: Bug (推空、数据不一致);设计缺陷(内存泄露、性能)
(4)客户端: Bug (注册异常、错误缓存);错误用法(连接打满)
(5)运维人员:误操作;配置错误(流量错配)
这些风险只是其中一部分,阿里巴巴在实践过程中,这些问题有些遇见的不止一次,双十一大促靠的是完善微服务高可用体系的建设,所以我们不能去避免风险,做高可用的本质是控制风险。
控制风险的策略:
注册配置中心在微服务体系当中是核心电路,牵一发而动全身,任何一个抖动都有可能较大范围的去影响整个系统
2.策略一:在风险发生时缩小影响范围
(1)集群高可用:
多副本:通过多副本(不少于三个节点)的部署
多可用区(同城容灾):可以在节点或者可用区发生故障时,把影响的范围缩小到这个集群中的一部分,例如:一个节点或者一个可用区的几个节点,并且如果能够做到快速地去切换,将故障的节点的自动离群,就能够进一步减少风险的影响。
(2)上下游依赖:
在系统设计时应该尽可能减少上下游的依赖,如果依赖比较多,可能会在被依赖的系统发生问题时,让整个服务的不可用了。例如:一般是一个功能块,依赖一个上下游,可能整个功能快就不可用。
如果有一些必要的依赖,要求这个依赖的系统也是高可用的。例如:我们通常必须依赖的 SLB ,或者 DNS
(3)变更可灰度:
每一次发展系统的发版,迭代发布应从最小的范围开始灰度,比如说按照 region 或者按用户;发布的过程中按照最小的机器力度一个一个地去进行发布,逐步的扩大变更的范围。一旦出现问题,也只是在这个灰度的范围内造成影响,所以它也缩小了影响范围。
(4)系统服务必须可降级,限流,熔断:
注册中心在出现异常负载的情况下,会降低客户端心跳续约的时间,或者降级一些非核心的功能,或者是降低一些同步的时间周期,通过牺牲一些实时性(短期内的这个数据一致性来提升整体服务的可用性);
针对异常流量进行限流,将流量的限制在评估的容量范围内,目的:为了保护一部分的流量是可用的;
客户端的异常,例如:在注册中心推送一些空列表的时候,能够降级到使用本地的缓存,暂时牺牲了列表更新的一致性来保证可用性的。
(5) 微服务引擎,MSE 的三节点同城双活架构:
上下游依赖经过了精简,缩小到上下游依赖只包含 SLB 和 RDS 。每一个上下游依赖都保证它是高可用架构,在多节点的 MSE 实例上,通过底层调动能力能够将这些节点自动分配到不同的可用区上面,组成一个多副本的集群,从而让整个架构是高可用架构。
3.策略二:进早识别,尽快处理缩短风险产生影响的时间:
识别是可观测的范畴, MSE 提供托管实例的监控和报警能力。
(1)云产品侧有更强的观测能力:
包括监控大盘;
告警收敛分级(是识别算法的问题,识别规则的问题,能够帮助我们有效的去过滤一些不必要的一些误报,以及针对大客户的专项的保障和服务等级的建设);
大客户专项监控;
容量监控;
SLA 建设。
(2) 快速处理:
应急响应的机制,每个故障在识别成功之后能够通知到正确的人,并且能够快速地执行预案;
预案在日常也得进行常态化的应急演练。这个预案是指不管是否熟悉此系统的人,都能够放心地去执行预案,需要有一套非常有含金量的技术支撑。
(3)目前 MSE 注册配置中心提供的服务等级是99.95% SLA 的保障。
4.策略三:减少触碰的风险的次数
减少不必要的发布,比如说遇到重要事件例如大促就进行封网
从概率角度来说,不管风险的概率有多低,总是大于零。经过不断的尝试,风险发生的概率就一定会无限趋近于100%。
5.策略四:降低风险发生的概率
(1)架构升级和改进设计:
Nacos2.0 (不仅在性能上做了提升,也在架构上做了优化)
数据结构的升级,从 Service 级粒度提升到 Instance 级别分区容错,可以保证在数据出现不一致的情况下,不会将整个服务的数据发生问题。
升级连接的模型(长连接),优点是能够请求处理线程有更好的管理和依赖,并且对连接的数量有更低的要求,不会有那么多短连接建立上来,而且对 DNS 有较弱的依赖,能够在架构上减少发生高风险的概率。
(2)提前发现风险的能力:
提前是指在设计/研发/测试的阶段就尽可能早地去暴露潜在的风险。例如:
通过提前做容量的评估预知容量风险能力水平;
通过定期的故障演练来提前发现系统上下游环境是不是具有风险,并且可以验证自己的系统在风险发生时,健壮性建设是否完备;
以及应急响应能力是否能够跟上。
(3)大促高可用体系:在不断的做压测演练,去验证系统的可靠性和弹性,并且在观测追踪系统的问题,不断的验证限流降级预案等可执行性