依赖简化

在分布式或微服务系统中,服务肩负不同职责,服务间必然存着依赖关系、往往系统复杂度的根源除了业务的本身复杂度,就是设计不恰当的耦合关系、或者服务划分不合理。在实际开发过程中,对单体服务进行重构的时候并不多。更多的时候,我们一开始做服务架构时便在使用微服务的架构模式。随着系统需求的渐渐复杂化,我们会发现,服务间的耦合越来越严重,甚至出现了循环依赖。这种时候我们不得不质疑自己,当初的模块是否划分的足够清晰,下面看几个列子。

依赖简介

上面三张图,描述常见的几种服务依赖关系。

图一:循环依赖

A依赖B,B依赖C,C依赖A,循环依赖会有很多危害,循环依赖让事情变得复杂,架构设计目标是简单,最大程度地减少软件不同部分之间的整体耦合。 较低的耦合意味着更高的灵活性,更好的可测试性,更好的可维护性和更好的可理解性。

循环依赖可能导致后果如下:

  • 单个单元的测试包含所有单元的测试
  • 难以对计划的变更进行影响分析。
    • 服务相互依赖、相互影响、耦合严重
    • 难以对计划的变更进行影响分析。

出现这种后果的原因如下:

  • 数据冗余,数据冗余是导致服务循环依赖的主要原因,为了保证多个服务之间数据的一致性,某个服务对数据的修改要同步到其他服务,保证其他服务冗余字段的信息准确。
  • 服务职责模糊,服务职责模糊是服务定义、职责模糊,导致上游服务和下游服务相互调用,出现这种情况,是否能够给出对应的解决方案。
    • 对业务理解不透彻,不能针对业务对服务进行合理拆分。

图二:无环有向依赖图

A同时依赖B、C,B依赖D、C依赖E,无环有向依赖图,对于这种调用关系,很容易清晰的明白各个服务职责,职责单一、可以针对需求或问题进行影响分析,便于测试,在架构设计中,比较推荐这种调用关系,无环有向依赖图,值得注意的一点是:层级不可太多,如何层级过多,也会带来稳定性问题和性能方面的问题。

服务依赖原则

在架构设计设计中,往往可以通过架构设计原则或者方法,来避免出现循环依赖,约束服务间通信方式,还需要定期通过这些原则来审视我们的系统,找到循环依赖问题并进行优化。

服务依赖的几条规则:

  • 上层服务可以调用下层服务。
  • 同级服务之间不能产生依赖关系,及不能产生调用关系。
  • 下层服务不能调用上层服务。
  • 服务之间的调用关系只能是单向的。
  • 层级最好不超过3层
  • 服务间尽可能通过领域事件(异步)的方式来实现

检测&打破循环依赖

想要消灭掉循环依赖单靠设计原则是不够的,一方面可以通过服务依赖原则去约束,还需要技术手段主动帮助我们发现循环依赖问题,双管齐下才可以。试想下,我们开始微服务架构之后,我们的很多服务变成分布式的了,并且我们对服务进行了拆分,拆分之后,用户的一个请求进来,会依次经过不同的服务节点进行处理,处理完成后再返回结果给用户。那么在整个处理的链条中,如何发现循环依赖呢,可以通过调用链监控帮助我们检测发现循环依赖,从而打破循环依赖。

调用链监控

调用链监控是在微服务架构中非常重要的一环。它除了能帮助我们定位问题以外,还能帮助项目成员清晰的去了解项目部署结构,一旦服务出现几十微服务,甚至更多,相信在运行时间久了之后,项目的结构很可能就是下面图片这样了,在这种情况下,团队开发者甚至是架构师都不一定能对项目的网络结构有很清晰的了解,那就更别谈系统优化了。

调用链监控具体可以帮助我们做那些事情呢,下面就一起来具体看一下「调用链监控」的作用有哪些:

  • 服务网络拓扑图
    • 通过调用链监控中记录的链路信息,给服务生成一张网络调用的拓扑图,通过这张图,我们就可以知道服务之间的调用关系是怎样的,以及系统依赖了哪些服务。并且还可以起到监控全局服务的作用。
  • 快速定位问题
    • 在分布式系统一个请求可能会经过多个服务节点,如果有任何一个节点出现了延迟或者问题,都有可能导致最终的结果出现异常,有的时候不同的服务节点甚至是由不同的团队开发的、部署在不同的服务器上,那么在这么错综复杂的环境下,我们想要排查出是链条中的具体哪个服务节点出了问题,非常困难,那么有这么一套调用链监控系统就能让开发人员快速的定位到问题和相应模块。
  • 优化系统
    • 优化系统也是「调用链监控」很重要的一个功能。因为我们记录了请求在调用链上每一个环节的信息,我们就可以通过这个来找出系统的瓶颈,做出针对性的优化。还可以分析这个调用路径是否合理,是否调用了不必要的服务节点,是否有更近、响应更快的服务节点。通过对调用链路的分析,我们就可以找出最优质的调用路径,从而提高系统的性能。
  • 团队成员自律
    • 对团队开发人员的帮助也是非常大的。因为团队所有成员都可以通过这个调用链监控系统看到系统各个模块的状态,相当于给了开发同学一个放大镜,以前开发同学完成项目交付后,只要没有出现问题,可能不太关心系统的优化,但是有这个调用链监控系统之后,哪个模块性能高,哪个模块问题大,一眼就能分辨,通过这么一个看板,开发同学慢慢的也会对自己负责的模块有更多的责任感,也会很自觉的去优化自己的模块。这种习惯的养成,对研发团队而言,非常的重要。

调用链监控,业界也有很多主流的调用监控系统、例如:CAT、Zipkin、Pinpoint、Skywalking等等。可以下去了解下。

循环依赖检测

Java生态在这方面做的比较好,本身支持循环依赖检测、防止这类带到线上。

例如:RPC框架Dubbo在启动时检测依赖的服务是否可用,不可用时会抛出异常,防止Spring初始化完成。这种情况我们就叫做RPC服务间循环依赖。出现了循环依赖,必须有一方先启动。所以这种问题是一定需要解决的。

例如:Spring bean的循环依赖,检测循环依赖相对比较容易,Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明有循环依赖了。

小结

微服务架构设计提倡服务拆分、小而独立,便于业务快速迭代,故一个软件系统往往拆分很多服务,大部分业务需求需要多个服务配合才能完成,在对架构理解不是很透彻的情况下,研发工程师往往倾向于采用更容易的熵增方式实现业务功能,在这种情况下,循环依赖是一个非常容易发生的坏味道,对系统的健康具有巨大的危害。对于循环依赖,不能只靠设计原则来约束团队成员,可以通过技术手段或工具帮助我们发现系统中循环依赖问题。通过可视化的方式找到系统的循环依赖,针对此就可以对症下药,消灭坏味道。

谨慎变更

谨慎变更是告诉我们对线上的任何变更都需要慎重,慎之又慎,原因是线上90%的事故或故障都是变更引起的,变更范围包括需求变更、配置变更、代码变更、表结构变更等,对这类变更需要对其进行管理,如果把事故比作火灾,那么稳定性建设的核心就是围绕系统的风险隐患,建立“防火墙”,所以稳定性建设是持久战,“保持敬畏,坚持防范”。

互联网公司的研发模式基本小步快走,高速迭代,快速试错,及时调整,一个业务每周发布十几次的变更都是很正常的,原因是可能需求上线、bug修复、架构优化调整等等,所以变更是频繁的操作,变更的操作打破了线上原本稳定运行的状态,因为引入了新的变量,故变更是研发最高危的动作,为了应对这样的情况,一方面通过变更规范性来对变更管理,另外一方面通过技术手段对变更管理之变更三板斧。

变更规范性

变更流程规范

  • 严格遵循团队内部代码合并规范性,包括Merge Request,保证上线的代码是经过严格测试和审核通过。例如本地开发环境-> 本地开发环境 -> 开发环境 -> 预发环境 -> 线上环境的发布流程,严禁未经上一个环境测试的代码提交到下一个环境。
  • 耐心变更,是指发布的过程中,遵循发布流程,先灰度,在小流量,在全量发布,每发布一个阶段,应观察一段时间,确保发布的内容被验证,防止未能验证到的代码,或者可能存在风险的代码,带到线上环境。如此在故障场景下可减小故障范围。同时做好回滚措施,异常场景下可缩短故障时间。
  • 发布的过程中,必须关注业务监控指标、告警等。
  • 存在风险或者重大的变更必须通知受影响业务方,做好应急措施。
  • 变更事项需要审核机制,确保每一次发布都被确认。
  • double-check 原则

变更时间规定

  • 节假日前不变更,严禁在重要活动、节假日前后发布,默认情况下,周五也不准搞事情(发布)。
  • 高峰期不变更,严禁在业务流量高峰时间段发布,对于一般的变更,请在周一至周四中低峰时间段发布,对于重大变更,请在凌晨发布。

变更频率规定

  • 尽可能减少重大变更发布,拆分多个小功能点,独立发布。
  • 严禁多功能合并发布,包括代码搭顺风车上线,建议分开上线。
  • bug修复应与产品迭代变更分开。
  • 对于有一定的用户量的产品,尽可能控制发布频率。

变更三板斧

随着业务发展,系统逐渐复杂,只有变更规范性应对变更管理,往往是不够的,上述更多变更事前的规范性,尽可能把风险消灭在前期,那么也很有可能风险被带到线上,为了应对这样的情况,变更三板斧自然就出现了,变更三板斧更多是帮助我们发现问题,问题提前被验证,出现问题可回滚,可快速止损。

变更可监控

在变更的过程中,有效的监控比人工反馈或者验证响应更快,也会减少故障的持续时间进而降低影响。而没有监控的变更就像是摸象,甚至是出现系统出问题了,都需要等用户来告诉你,完善且有效的监控在变更过程的重要性,不言而喻,针对完善且有效的监控需要回答三个问题:是否有问题发生?哪里发生了问题?发生了什么问题?这三个问题是递进的关系,可以从问题倒推对监控的覆盖程度与范围,监控不单单是技术指标,更多的是结合实际业务场景去设计,才能够更加细化地感知异常。

变更可灰度

在变更的过程中,不可将变更的内容直接发布到线上环境中,有些变更的内容风险非常大,没有充足的时间,直接上线,可能是天灾,灰度发布(有名金丝雀发布)是黑与白之间,能够平滑过度的一种方式,灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。值得注意是,灰度需要有耐心,尽可能让其用户对灰度发布的内容进行验证,让用户真实的去参与实际的使用,通过监控和数据反馈,如果没有实际用户参与,灰度就失去了其意义。

假设:常见的对bug修复,可能只在预发环境测试没有问题,再次发布到小流量阶段,但是并没有经过小流量阶段验证,又再次发布到线上环境,到生成环境才发现问题,这个时候问题已被放大,所以要严格遵循变更流程。

变更可回滚

在变更的过程中,难免出现事故,出现事故该如何快速止损呢,回滚是故障恢复最好手段是各种预案,而回滚也是预案中最普遍,最有效的方式,值得注意的是回滚这个操作,强调的是何时回滚?如何能确保回滚正确性?要知道,系统并不是天然可以无缝回滚的,想要系统具备回滚的能力,需要在架构设计和实现阶段付出额外的精力的,可回滚的本质是系统的兼容性设计。

例如:常见的“只增不改不删”,一个 API 内要调整很多实现逻辑才能满足新业务的需求,此时不妨直接新增一个 API ,两个 API 保持参数一致,那么一旦新 API 有异常直接切换回旧的 API 即可。

小结

谨慎变更是为了提高系统的稳定性,也是稳定性建设尤其重要的一环,原因是线上90%的事故或故障都是变更引起的,对于谨慎变更这块,一方面通过变更规范性加文化意识宣贯引导,约束变更让变更更加的规范性,尽可能将风险提前暴露和消灭掉,另一方面通过变更三板斧对变更过程中的故障进行管理,包括变更过程的故障发现、故障预警、及时止损,减小影响范围。

关于稳定性建设之道大纲速览

目录:关于【稳定性建设之道】大纲速览_jackl-CSDN博客从理论、方法、实践多维度阐述稳定性、从全局视野出发、由内到外、从组织到文化,从风险识别到风险预防、从面向失败到主动失败多个阶段,多维度去描述如何打造一个高可用的系统。https://blog.csdn.net/liu_dudu/article/details/122333724

第五篇:稳定性之提升团队潜意识【依赖简化、谨慎变更】相关推荐

  1. 第八篇:稳定性之提升团队潜意识【及时复盘、开关设计】

    及时复盘 复盘,本是一个围棋术语.指下完棋,棋手重新摆一遍下棋的过程,探讨得失,总结有无更好的应对招数.而现在,这个词已经被泛化,许多企业把它赋予了管理学意义.联想最早引入"复盘" ...

  2. 第七篇:稳定性之提升团队潜意识【提前预防、裕度设计】

    提前预防 提前预防是告诉我们从失败中学习,防止同样的故障再次发生,海因里希法则告诉我们,一次重大事故的背后必然有一百次未遂事件和几十次轻度损失.这个法则对于我们有两个启示:一是事故的发生必然有其关联起 ...

  3. 第四篇:稳定性之提升团队潜意识【及时止损、监控报警】

    1.及时止损 在故障发生时,我们首先考虑也是最重要的是及时止损,及时止损的前提是快速定位故障源,因为在很多分布式系统中,一旦发生故障就会出现"多米诺骨牌效应".也就是说,系统会随着 ...

  4. 软件测试bug不能重现,软件测试第五篇:如何提升bug重现的概率?

    原标题:软件测试第五篇:如何提升bug重现的概率? 作为测试人员,经常要求去重现bug.如何更好更快的重现bug,是测试人员必备的基本功之一!也是测试人员能力的体现.通常某个线上真实用户提出有某某问题 ...

  5. python爬虫工程师面试自我介绍范文_计算机工程师面试自我介绍范文五篇

    自我介绍在面试中是必然要过的一关,自我介绍得好不好也直接影响到面试的效果,那么该如何做到与众不同又精彩呢?下面是小编给大家搜集的范文五篇,希望有帮助到大家. 计算机工程师面试自我介绍(一) 面试官您好 ...

  6. 高中计算机听课总结,中学新信息技术老师听课心得体会五篇

    <中学新信息技术老师听课心得体会五篇>由会员分享,可在线阅读,更多相关<中学新信息技术老师听课心得体会五篇(14页珍藏版)>请在人人文库网上搜索. 1.中学新信息技术老师听课心 ...

  7. 快狗打车CTO沈剑:如何利用计划管理提升团队效率和产能

    本文根据沈剑老师在[deeplus直播第237期]线上分享演讲内容整理而成.(文末有获取本期PPT&回放的方式,不要错过) 沈剑 快狗打车CTO 到家集团技术委员会主席,互联网架构技术专家: ...

  8. 计算机组装与维护教学工作计划,计算机教学计划范文五篇

    计算机教学计划范文五篇 时间的脚步是无声的,它在不经意间流逝,我们又将接触新的知识,学习新的技能,积累新的经验,是时候抽出时间写写计划了.那么计划怎么拟定才能发挥它最大的作用呢?下面是小编为大家整理的 ...

  9. 如何从 0 到 1 搭建生鲜 B2B 的技术体系(B2B 技术共享第五篇)

    宋小菜一直聚焦做中国生鲜的分销网络 宋小菜从2014年年底创建,到今天为止,3年多的时间只做了一件事情,摸索到蔬菜供应链的上游,为什么宋小菜要把业务持续往"上"做了?做B2B业务, ...

最新文章

  1. Python3中内置函数callable介绍
  2. Java Vector与ArrayList的区别
  3. java程序不能编译_救命-JAVA程序不能编译!
  4. Linux mke2fs 硬盘格式化
  5. springmvc重定向到另一个项目_SpringMVC——redirect重定向跳转传值
  6. Java日志操作总结
  7. codeforces 966c//Big Secret// Codeforces Round #477 (Div. 1)
  8. 《阿甘正传》,看了很多遍,是否留意到这个镜头???
  9. Node:正则验证手机号和身份证号
  10. celery 停止任务_Celery 周期任务运行一段时间后意外停止
  11. 字母串按照字典序排序
  12. 数据分析的一些简单思路总结
  13. easyExcel 处理ExcelDataConvertException异常,获取异常的数据行列值等信息
  14. 怎么把WORD中插入的图片改为统一尺寸的,看这里,文档中图片怎么改成同样大小
  15. 都柏林圣三一大学计算机科学,都柏林圣三一学院简介-录取要求-就业情况-录取案例-就读体验-WordSunny留学...
  16. php 命格算法,八字格局中的弃命格mdash;mdash;从势格
  17. 如何有效设计你的调查问卷?
  18. linux 万能五笔安装
  19. Cloudera Manager环境搭建【二】
  20. 【STM32】OLED显示程序

热门文章

  1. 两天碾转两个学校办卡地推
  2. 基于单片机的电子琴系统设计(#0424)
  3. MyBatis-Plus——MyBatis-Plus概述与集成
  4. docker:报错docker: Error response from daemon: Mounts denied:
  5. NOIP提高组1580~1590集合答案
  6. 玩转STM32F0 Value Line Discovery 之 深入理解 SYSTICK定时器
  7. 成都计算机应用研究所夏令营,北京师范大学环境学院2015年大学生暑期夏令营...
  8. 数据中台到底如何落地实现【含架构图及代码】
  9. BigCommerce vs WooCommerce –哪个更好? (比较)
  10. 如何建立高质量团队-《克服团队协作的五种障碍》笔记与心得