写点什么

从二十个严重的配置故障中我们能学到什么?

  • 2019-12-24
  • 本文字数:4293 字

    阅读完需:约 14 分钟

从二十个严重的配置故障中我们能学到什么?

配置故障是运维人员在工作中经常会遇到的问题,如何才能避免配置故障的发生呢?本文作者列出了自己职业生涯遇到的 20 个不同类型的配置故障,并分析了故障发生的原因,提出了相关的解决方法。

配置变更的痛点

时效性,很多配置变更的场景,其生效时间是有明确要求的,尤其是止损相关的操作。如流量调度的配置生效时间不超过 5min,这是由 SLA 所决定的。因为 5min 的生效要求,所以这类配置变更基本上不会进行灰度,直接就全量生效了。


动态化,在上下游关联关系的场景中,服务的 IP 地址列表和数量均会发生变化的,站在整个系统角度去看,可能每时每刻都会有服务因扩容、缩容、故障转移而产生 IP 列表的变化,加之这类配置是最终一致性的特性,因此,就很难对语义内容的正确性做及时准确的判断。


差异化,同一服务的不同实例或者不同集群间,配置会有一定的区别。以监控系统为例,因为每台机器上部署的服务组合不相同,那么每台机器上需要采集的内容就不相同,那相应的监控配置也会不同。许多的机器生效的配置不同,版本不同,那么要想检查哪些机器未生效最新配置,未完全生效配置,就有困难了。


碎片化,每个服务都需要配置管理,但现实却是大多数服务都是自己写的这套逻辑,且实现非常之简单。如果现实是建立在大多数服务自己实现配置管理的基础上,那么想要做到相对统一的标准规范,你就需要做各种对接和适配,开发各种外挂,持续处在一个较低的层次上。配置中心成熟的开源解决方案有很多,因此内部开发人员也少有动力基于现状写一套适配的方案,大家都会说推动改造是最好的,那改造之前呢怎么办呢

二十个严重的配置故障

笔者曾长期负责配置服务的运维工作,也经常参加公司的故障复盘会,感慨于配置故障影响的严重程度,因此将过去多年和配置相关的各种服务故障脱敏后进行罗列,希望对大家有所帮助。限于篇幅的关系,无法对每个 case 进行准确详尽描述,仅描述故障原因部分,因此阅读下面的 case,需要读者具备一定的相关背景才能更好的理解(本文中罗列的 case 较多,有内容不合适的地方,可直接联系笔者处理)


case1:在 WAF 中部署了配置错误的规则,其中一个规则包含有一个正则表达式,导致节点 100%CPU 占用。和 CloudFlare WAF 的故障是较为相似的


case2:某服务访问数据库错误,获取合法用户列表的结果为空值,该服务认为没有合法用户,将所有的用户请求全部封禁,导致系统完全不可用。和阿里云 20180627 的故障较为相似的


case3:每台物理机上均有一个单机部署器,单机部署器定期从服务端同步配置,用以在单机上部署需要的客户端列表。因为网络的问题,配置被截断,部署器只获取了上半部分配置,部署器基于此进行更新,所有未在配置中的服务被全部卸载,影响极为严重


case4:计算模块对加载的处理规则数量进行了限制,单个租户最大可处理 1000 条规则,经过几个月的使用后,某个租户的规则数超过 1000 条,计算模块全部 coredump


case5:服务启动前需要从远程加载相关配置,某次变更添加配置条目较多,服务请求配置超时后,不断重新启动,直至将配置中心打垮,进而影响多个业务,导致系统彻底崩溃


case6:Zookeeper 的 initlimit 设置为 5(意思是实例启动后可以有 10s 的时间来同步数据),该数值对于大部分集群来说,都没有问题,但是如果 ZK 集群的快照体积超过 1GB,那么节点重启后就可能无法在 10s 内同步完数据进而导致节点异常


case7:Agent 上传给服务端的数据包出现了异常,在头部信息中,100KB 的体积变成了无限大,然后后端模块就按照该值进行内存分配,因为超过 Ulimit 的限制,所以 coredump 了,一部分服务器异常后,Agent 继续将请求发送给剩余的服务器,直到集群全部被打死为止


case8:通过配置服务获取下游服务列表,运维人员误将服务下所有实例从配置中删除,而该服务也未使用系统提供的熔断阈值,导致从配置服务中获取该服务列表为空,其他依赖服务加载了该配置后,导致服务整体故障


case9:新上架的交换机未添加完整的 ACL 规则,导致线下服务请求到线上集群中


case10:用户提交了语法结构不正确的配置,然后该配置下发到了后端,所有加载该配置的后端模块全部 coredump 了,后端模块使用了通用的语法校验库,但和前端使用的校验库不同


case11:后端服务异常后,触发了自动降级(通过修改 Nginx 的配置文件来实现),修改配置文件出现了逻辑错误,该配置通过了语法校验并立即进行了全量自动更新,导致集群整体崩溃


case12:将某台服务器上的 stats.conf 文件同步到全部 nginx 集群上,忽略了 allow 字段的 ip 地址不同,致使 lvs 认为监听的后端 nginx 全部故障,系统直接出默认页面了


case13:批量删除线上服务器的日志,因路径中包含特殊字符,运维系统未能很好的处理该字符,只保留了特殊字符前的路径,导致线上服务器根目录被清空


case14:配置项结尾多了特殊字符,导致策略匹配全部失败。原因是 windows 下的文本文件换行符是\r\n,linux 下的换行符是\n,在 linux 下 vim 打开 windows 的文本文件,在行尾会显示^M 字符


case15:通过配置服务获取下游服务列表,因下游服务列表包含了四万多个 IP 地址,导致获取超时,服务继续使用过期的下游列表,而该过期的下游列表中无效实例逐渐增加,最后导致服务连续重试到无效实例,流量被丢弃


case16:配置中心对外提供配置下载服务,其 LB 的负载均衡策略使用了随机策略,因下载集群规模超过百台机器,配置更新需要一定时间,在此期间,请求配置中心获取的配置会不停的在新旧版本之间变化,导致相关的服务被不停的卸载,升级,无法提供服务


case17:配置中心的负载均衡策略使用了 Ip_hash 策略,部分下载集群数据未更新,导致被分配到这些集群的服务,无法获取最新配置,且多次重试依然无效,导致流量统计始终缺少 20%的流量,对收入造成严重的损失


case18:高防回源携带的头部字段中新增的内容与源站 iis 配置不兼容,导致回源请求被拒绝


case19:named 服务在重载配置时,产生了新的进程但老进程没有正常退出,服务请求数据时,将请求打到了老 named 的进程,该进程的配置没有更新,导致用户拿到的结果不符合预期。类似的问题,nginx 也有,在很多开源软件上也都有存在


case20:自研 nginx 的扩展来实现 upstream 的定位,hash 桶的大小设置为 1024,因 ip 重复个数较多,超过了 hash 桶的大小,导致 hash 分桶策略不断的进行 rehash 任务,请求全部被卡死

故障改进

对于上述的故障,我们从加强测试,加强数据校验,集群隔离,灰度发布,缓存和熔断六个维度来看各个 case 的适用性,结果如下图所示。


加强测试加强校验集群隔离灰度发布缓存熔断
case1适用适用适用
case2适用适用适用适用
case3适用适用适用适用
case4适用适用
case5适用适用适用
case6适用适用
case7适用适用适用
case8适用适用适用
case9适用适用
case10适用适用适用适用适用
case11适用适用适用
case12适用适用适用适用
case13适用适用适用
case14适用适用适用
case15适用适用
case16适用
case17适用
case18适用适用
case19适用适用
case20适用适用
17137764


假设笔者的给出的改进方案是正确的,对统计结果做如下分析:


  • 加强测试,从有效性来说,该方案可以搞定 85%的故障,如边界值的问题,异常输入的问题,特殊字符串的问题等。但是对于部分场景,加强测试可以搞定,但成本非常高,例如 WAF 的规则问题,不同的用户,配置的规则不同,如果要在测试阶段解决,那就需要对所有用户的所有规则进行测试,且要有足够丰富的请求组合,这时候,可行但成本很高。还有,加强测试虽然可以解决很多问题,但没有从本质上彻底消除问题,且依赖于测试团队的经验和能力,结果并不可控。

  • 加强校验,从有效性来说,该方案可以搞定 65%的故障,以 case2 获取空值的故障来讲,对请求结果进行校验,完全可以避免该问题,且这是程序机制天然具备的,并不依赖于人的经验和能力,因此效果更好。另外,加强校验,并非局限于对空值的校验,还包括配置文件完整性的校验,数据包合法性的校验,配置文件的版本、时间戳、更新时间的校验,对特殊字符串容错的能力,还提供一些故障场景下的兜底访问策略,同时还可以将配置变更的信息以 http 接口进行暴露,便于监控。美中不足之处在于,如果对每个模块分别实现上述的功能,那成本太高了。

  • 集群隔离,笔者之前最为推荐的能力建设内容之一,本次居然只能解决 35%的故障,究其原因,主要在于很多业务虽然隔离部署,但依赖了相同的配置文件,且大部分是高频热加载的,因此集群隔离在此处,略显苍白。

  • 灰度发布,这也是笔者最为推荐的能力建设内容之一,本次也只能解决 35%的故障,主要是因为大部分的配置变更是没有灰度发布的,直接靠程序的定时轮询热加载,因此灰度在此,也略显苍白。


综合来看,三个建议:


  • 将校验,缓存,熔断等相关的能力合并在一起,在通用的配置服务中实现,会是比较好的方案,退而求其次,如果没有通用的配置服务,也应该具备这些能力。

  • 将配置变更尽可能的视为一种上线,涵盖从版本提交,代码检查,测试,灰度发布,效果监控等各个环节,也能够更好的保障稳定性,毕竟很多配置是最终一致性,而非强一致性的,因此,用时间来换取稳定性,也是值得的

  • 将强一致性转为最终一致性,问题就不会那么棘手了。以账号密码变更为例来说明,账号密码变更是强一致性要求的,但是如果通过新增一组账号密码逐步进行替换,全部替换完毕后删除旧的账号密码,则就将强一致性转为最终一致性了。


还有兜底建议:


  • 通过资源限制+SSH+Puppet 多种方式的互备,确保任何场景下,不论是 sshd 异常,还是 cpu 打满,都能够通过批量操作服务器快速止损,决不要出现无法登录服务器的惨剧

场景化建议

热加载配置的场景,尽量使用配置中心这种解决方案,类似于上文的加强校验,缓存,熔断等等,都是标配能力了,而且一旦发现了潜在的隐患,通过升级 lib 库,大家都能避免发生同类问题,效果极好。当然,你得用好才行,胡乱使用 zookeeper,最后导致各种故障,然后怪罪于 zookeeper 有问题,人家很冤枉啊。


需要通过重载配置文件才能生效的场景,则尽量使用集群隔离+灰度发布+加强校验的解决方案,以 DNS 为例说明,不同的 zone 由不同的集群来处理请求,每类 zone 再按需实现同城多活/异地多活,并新增小流量集群,尽量杜绝跨集群的变更操作,对每次变更都要进行严格的自动化校验,并分批次灰度生效,通过提升实时监控能力来降低批次间的时间间隔,进而减少故障的发生。


在整理上面资料的同时,配置故障让我联想到和无性繁殖有些类似,文末的参考资料中附带了香蕉和咖啡树的故事,有兴趣的读者可以看看。


扩展阅读:


香蕉可能要灭绝?还不是第一次?香蕉:救救孩子吧…


为什么英国人对茶情有独钟而不是喜欢咖啡?背后原因你一定想不到


2019-12-24 09:402168

评论 3 条评论

发布
用户头像
多级缓存也应该是配置类服务的一种兜底能力
2022-05-30 21:30
回复
用户头像
需要把改进能力放在case后面进行下标注,让大家在当时就能够认可改进内容,从而认可统计结果

2020-04-13 19:16
回复
用户头像
google在2020.03.26的服务故障可以更新进来
2020-04-13 19:13
回复
没有更多了
发现更多内容

实战邮件攻击简要分析【网络安全】

网络安全学海

网络安全 安全 渗透测试 WEB安全 漏洞挖掘

青藤“基于工业互联网的安全方案”成功入选信通院守卫者计划

青藤云安全

主机安全 互联网安全

单线程性能炸裂 英特尔以Sapphire Rapids强势角逐AI计算市场

科技之家

K8S集群无法通过Service Name访问的故障

领创集团Advance Intelligence Group

Python接口自动化核心模块 - 数据库操作和日志

伤心的辣条

程序员 程序人生 软件测试 接口测试 Python自动化测试

【ELT.ZIP】OpenHarmony啃论文俱乐部—硬件加速的快速无损压缩

ELT.ZIP

OpenHarmony 压缩算法 ELT.ZIP 啃论文俱乐部

【ELT.ZIP】OpenHarmony啃论文俱乐部—一种深度神经网压缩算法

ELT.ZIP

OpenHarmony 压缩算法 ELT.ZIP 啃论文俱乐部 深度神经网

主数据管理平台功能模型介绍

agileai

Java 数据治理 数据模型 主数据平台 功能模型

传统企业数字化转型,到底难在哪里?

SoFlu软件机器人

企业如何建设知识管理系统

小炮

【ELT.ZIP】OpenHarmony啃论文俱乐部—gpu上高效无损压缩浮点数

ELT.ZIP

鸿蒙 压缩算法 Openharmony啃论文俱乐部 ndzip

安心+10000

天翼云开发者社区

先睹为快 | 卓越示范中心ETB003云原生安全实验测试床

青藤云安全

容器安全 信通院 云原生安全

Elux-从"微前端"到“微模块”

hiisea

前端框架 微前端 微模块 elux

小程序开发真的可以取代APP软件开发设计吗?

开源直播系统源码

软件开发 小程序开发

云原生存储解决方案Rook-Ceph与Rainbond结合的实践

北京好雨科技有限公司

Kubernetes PaaS Ceph rainbond

【赛事预告】云上开发,高效智能——第二届阿里云ECS CloudBuild开发者大赛即将启动

阿里云弹性计算

开发者大赛 自动化运维 云上运维 机密计算 内存缓存

Vue-9-计算属性的属性

Python研究所

6月月更

天翼云为欧拉社区贡献首个C++热补丁 加速推进联创技术落地应用

天翼云开发者社区

详解MOVE PROTOCOL的测试版,让健康运动如影随形

鳄鱼视界

EMQ作为首批创始会员单位,加入SAP可持续发展与实践战略联盟

EMQ映云科技

物联网 IoT SAP emq 6月月更

What are the uses of LED display?

Dylan

LED LED display

BI的落寞,低代码会重演一遍吗?

ToB行业头条

外呼机器人7大难题,看网易云商如何攻破?

网易智企

AI 机器人

详解MOVE PROTOCOL的测试版,让健康运动如影随形

西柚子

数字先锋| 助力打造国有资本运营升级版 中国国新构建数字化转型新格局

天翼云开发者社区

小程序容器技术,加速工业互联网平台建设

Geek_99967b

小程序 工业互联网 小程序容器

不愧是美团内部“接口自动化测试学习笔记”这细节讲解,神了

伤心的辣条

Python 程序人生 软件测试 自动化测试 接口测试

从小白到架构师原来是这样修炼出来的

C++后台开发

架构师 C++后台开发 软件架构师 服务器架构师 C++架构师

数字先锋 | 牵手中资医疗医药,开创医疗医药应急保障服务新格局

天翼云开发者社区

天翼云电脑打造极致流畅与安全 助企业数字办公升级

天翼云开发者社区

从二十个严重的配置故障中我们能学到什么?_软件工程_焦振清_InfoQ精选文章