求解质量熵
在前面的小节中,我们从黑天鹅事件谈到了蝴蝶效应和墨菲定律。一言以蔽之,将软件研发质量做好并非易事。质量是一个综合命题,涉及业务的准确性、稳定性和可用性等,比如某厂商在大促的几个小时内无法交易、收藏夹的商品丢失、用户享受的优惠不符合预期、营销规则难以解释等。
黑天鹅告诉我们,要走出经验主义,就不要将自己知道的太当回事,我们不知道的事比我们知道的事更有意义;蝴蝶效应告诉我们,要及时感知问题、止损和熔断,避免问题范围扩大甚至影响到其他相关领域;墨菲定律告诉我们,你知道却忽略的问题终会爆发!
在前面的小节中还讲解了让人难以掌控质量问题的复杂因素,如下所述。
◎ 业务高速发展带来的变化。
◎ 技术债。
◎ 人、流程和文档的博弈。
◎ 采用了不能掌控的工具和框架。
◎ 复杂的问题域。
◎ 质量意识。
为了应对以上复杂因素,这里从如下几方面来思考对策。但是,如同没有银弹一样,也没有万能解药。
运用敏捷思想
敏捷开发思想以用户的需求进化为核心,迭代式、循序渐进地进行软件开发。在敏捷宣言中是这样说的:我们一直在实践中探寻更好的软件开发方法,在身体力行的同时帮助他人。由此,我们可以建立如下价值观:
◎ 个体和互动优于流程和工具。
◎ 能工作的软件优于详尽的文档。◎ 客户合作优于合同谈判。
◎ 响应变化优于遵循计划。
敏捷建模(Agile Modeling,AM)的价值观包含了极限编程(Extreme Programming,EP)的4个价值观:沟通、简单、反馈、勇气,还增加了1个价值观:谦逊。至少,我们明白了快速反馈的好处:做错了、做偏了可以马上校正。瀑布模型式的开发反馈必然是慢的,一位做医疗单机软件的专家说,他们半年才进行一次新版本发布,可见其中的提升空间有多大。
总结一下:基于敏捷的思想可以快速发布、纠正和调整,以满足用户的需求。
运用系统化思想
系统化思想就是通过类比、抽象、层次化等手段挖掘本质。很多时候,当软件系统在线上出现Bug时,我们会开展各种故障复盘并定下很多后续的行动点,但下次依旧会犯同样的错误。究其本质,一方面是我们将复盘的内容聚焦在单个事件上,对于更大体系的影响洞察不够;另一方面是未持续学习,不情愿承担问题。
但是,建立系统化思想其实是比较难的,太多人对建立新思想持抵抗态度。如萨提亚改变模式(见图6.17)所示,当我们适应了原有状态却需要面对改变时,我们会经历抵抗、混乱、改变主意、重新上路等过程,最后适应新的状态。
图6.17
之前,笔者所在的团队对深度复盘实践也是比较抵触的,通过大约1年的持续练习,才使我们对于问题或故障的认知及担当力都上了一个台阶。
技术债偿还计划
在6.4节提到,技术债的存在是软件质量无法得到很好提升的一个重要原因。对于遗留的技术债,很多开发人员很想解决,但是由于各种各样的原因,技术债越积越多。
关于技术债的偿还有如下4个有趣的观点。
◎ 技术人员水平不行、意识不够,代码越写越乱。
◎ 开发者都有一颗积极向上的心,但不知道如何做才好。
◎ 上行下效,没有靠谱的Leader、架构师,大家便都是懒惰的,不想去还债。
◎ 业务压力太大,赶着交付,没有时间清偿技术债。
这里总结了几个有效应对思路。
◎ 构建质量保障体系,让开发人员有勇气动手改造。比如进行接口测试、单元测试,通过持续集成进行反馈,这样开发人员在做重构的时候就有一些基本保障。
◎ 不要动遗留系统中没有出问题的地方,对于遗留系统中出问题的地方,修复并补充测试代码,更进一步地,对高危功能和模块做定向增强。
◎ 招募优秀的工程师,使好的工作作风和习惯影响整个团队。◎ 抓住痛点大做文章。比如,平时说持续集成,可能团队成员没有感受到其好处,那么出 Bug了再讨论讨论;复制粘贴来的代码总有不能满足更复杂需求的时候,这时讨论,大家就会发自心底地认同,觉得必须得重写代码了。改变人很难,但这样的机会不容错过。一定要抓住这样的机会,构建品质高一些的代码和质量防线。
抓住合适的时机做架构升级
在做软件架构升级的时候,一定要考虑时机是否合适。当一些重点战役型项目让你喘不过气的时候,去做理想架构肯定会碰壁。这里给出的一个观点就是技术、架构始终为业务服务,为商业服务。无论是从走出舒适区,还是从架构的发展来讲,一定要找准时机做架构升级,这个升级要基于对业务本质的不断认知,否则就会南辕北辙。
在一次重要的架构改造过程中,笔者所在的团队对新的技术架构方案的确定比新业务的来临早了3个月,这样刚好通过一个小的业务需求使新的技术架构快速上线。新的技术架构刚好又在之后的新业务需求中派上用场,帮助我们快速地将商业项目落地。可见,3个月的时差足以改变许多东西。
因此要记住,要抓住合适的时机做架构升级。
总结一下:康威定律及其推论告诉我们要做什么事情,以及设定什么样的组织结构;同时做不同的事情,要允许有动态、弹性的组织结构,不要被组织束缚;更进一步,通过跨越组织、立足协同及赋能可以有更大的组织成效;技术债务不要等到“下雨天”才偿还,平衡做业务和平台架构发展的艺术取决于一定时间和环境下的目标,技术人员不要永远处于被驱动的状态!研发之痛,是一个复杂的调试性问题,没有银弹!
内建质量
前面讲技术债务和反馈的时候都提到了持续集成,从整体来讲,内建质量就是用更短的时间构建,以及用更快的速度反馈。同时,除了正确做事,还要思辨“做正确的事”。通过 ATDD、引流对比、串讲反串讲、评审、录制回放验证、接口回归测试等手段可以验证从需求到设计再到实现是否发生了变形。
内建质量=正确做事×做正确的事。
不迷信,不唯新、不唯上,实践是检验真理的标准
在技术选型上,我们要不迷信、不唯新、不唯上,建议尽早做小范围的可行性论证。比如对于之前流行的OSGi技术,采用它可以获得什么,其风险又是什么。
在引入一种新的技术栈的同时,会带来一层复杂度,而复杂度有一个天性:只能增加,不能减少,就像宇宙中的熵一样。比如,一旦开放使用某个接口,就很难将这个接口停用。一旦以某种高耦合方式引入某种技术,调整或者去除该技术的成本就会呈几何级数形式。
总之,在做技术选型时,要看看技术的成熟度、团队人员的掌握程度、收益和风险评估,一旦陷入泥潭则无异于梦魇之旅。为了避免陷入泥潭,我们可以基于风险的架构设计,采取可行性论证。
复杂的问题域:专项突破
前面提到,系统和问题域的复杂度都会增加出现Bug的风险。
随着业务的发展,人们对可用性的诉求也越来越高。比如从单机房部署演变成同城异机房,最后又演变为异地机房。因为有异地机房,所以 RPC 的路由复杂度增加;同样,在开发环境、线下测试环境下模拟几种部署方式也是有复杂度的。
对于这样一个庞大的系统来说,在每次发布新版本时不仅要完成功能用例的构建,还要完成性能的测试。那么,面对如此复杂的测试,我们该如何应对呢?答案是,除了需要构建功能回归测试环境,还需要构建性能回归测试环境,以保障每次发布的产品性能是没有降低的。
对于多机房部署这种情况而言,在技术架构上不但要考虑复杂度带来的诸多依赖产品的修改成本,还要考虑易用性和如何测试,甚至如何方便、低侵入地测试。因为一旦从单机房部署演变为多机房部署,问题的外延就翻倍了。比如:一个定时任务会不会同时在两个机房运行并导致数据重复;在机房切换时是否有缓存切换的问题导致业务不可用;数据复制延迟带来的不一致性对业务的影响;对数据复制的监控、对缓存的监控等,需要有全局的唯一性管理策略及业务兼容性方案,等等。
领导者的意识
一个公司的文化由创始人决定,一个团队的品质追求也往往由其领导者决定。领导者不自觉的保护主义及报喜不报忧等做法都会让问题变得严重。
团队成员一般向领导者看齐,所以,领导者看重质量,大家就看重质量;领导者有欺瞒行为,大家就有欺瞒行为;领导者若对问题熟视无睹,这个团队就糟透了。
创新解决方案
Perl设计者在Programming Perl书中提到,优秀的程序员有三大美德:懒惰、急躁和傲慢。为了减少总能量支出而不遗余力地努力的素质就是懒惰;受不了程序低效执行就是急躁;容不得对错误不管不顾就是傲慢。
要发扬程序员的美德,比如对于规则系统,如果不能构建上游的上千种场景,就可以思考新的解决办法。有人说做业务系统没什么追求和挑战,但是又有各种Bug,小事不想做,大事做不来。其实“小事不小”。
本文给大家讲解的内容是程序员架构修炼:架构的保障,质量与风险求解质量熵;
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。