1. 背景
空降接手了一个迭代多年的旧产品,领导希望在维持住现有业务支撑的前提下,对其技术框架进行升级改造,解决由来已久的"产品易用性差,BUG多,问题解决效率低,版本管理混乱“等用户投诉颇多的问题。
这并非个例,对于一个有着长期商业价值的软件产品,如果没有一个规范的开发管理流程打底,没有一群经验足够丰富的高水平研发和管理人员把控全局和关键节点,上面谈到的这些问题一定会很快爆发,并随着时间的发展愈演愈烈。
本文我们尝试探讨下,我们应该秉承哪些原则和操作方法,来逐步改变现状,让状况向好的方向逐步演进,尽量让各方都满意。
2. 面临的问题
正式开始介绍最佳实践前,先让我们看看问题有哪些。
- 产品已经经过多年开发,因为缺乏规范的管理流程和统一的技术标准要求,欠下诸多历史债。
- 虽然问题不少,但产品以商业化多年,并且因为行业特点,产品维护周期长,开发团队除了应对产品本身的既有开发计划,也需要支撑日益增多的运维需求。
- 团队研发人员占比少,能力缺失。问题爆发时以满足眼前为主,系统耦合性高,历史解决方案相互掣肘;缺乏对于问题的复盘和总结,重复性问题一再出现,解决方案无优化,响应速度慢。
- 系统架构技术环境复杂。同一类问题多种解决方案并存,不必要的链路深度,以及为了技术而技术,无视系统的应用场景强上"高大上"解决方案,使得系统运维成本居高不下。,
- 为飞行中的飞机更换发动机。整个工作里最难的部分就是这个了,在保证对现有项目支撑的前提下,实现这一系列的升级改造。不论从商业价值,还是技术实现上,领导也都不会贸然同意另起炉灶式的"优化"。
3. 秉承的原则
接下来,让我们看看针对上面这些问题现象,可以参考的最佳实践有哪些。
3.1 增加可观测性接口
软件产品最常被诟病的一点就是问题多,修复慢。针对这类问题,除了加强测试投入外,在研发侧,也要针对性地投入精力进行优化,可观测性上的持续投入就是一个非常好的尝试。
客户感受到的“问题多,修复慢”,本质根源还是问题解决效率低,问题多都是表象。毕竟如果你解决问题效率高的话,说明你对问题的了解已经相当全面,并且有着一整套成熟的解决流程,能够快速定位到问题,在这样的前提下,短期内问题就能被大范围规避和消除。
而想要加快问题解决效率,增加系统的可观测性必不可少。我们应该从以下几个方面投入精力:
- 减少沟通需求。针对团队各岗位之间在协作解决问题过程中,那些作为固定式的沟通内容,尽量将它们以"黑板"(你把信息更新在这里,我在需要的时候会自己到这里来查阅),规范的形式固化下来。最典型的例子就是售后与研发进行问题沟通时候,诸如问题系统部署位置,系统当前版本等等这些前置知识,在初次碰头时就进行一次性告知,而不是每次都得来一轮,反复拉锯式的沟通。当然更佳的方案是系统实现自描述 —— 让系统能够自己回答这些问题,直接杜绝这部分沟通需要。
- 能够快速查询系统各类内部状态信息。针对系统内处理的流程,梳理其对于系统内部各组件状态的影响(例如数据库,缓存,所依赖的服务等等),并提供相应的查询接口。
- 完善系统边界的日志记录。进程内部出错的可能性低,排错也方便,一般出现问题往往都是在系统边界区域,系统内部必须要提供一种机制 —— 动态开启/关闭边界详细日志记录的能力。甚至最好将这种动态启停粒度设置为单次调用 —— 形如zuul那种,传递一个debug参数,它就会将本轮调用中的详细日志记录返回给你。这对于问题调查将是大有裨益的。
- 上面这些功能,我们要的是方便快捷地做到,而不是仅仅能做到。为了使用你提供的功能,我得准备进行一堆前置准备 —— 调用一秒钟,准备五分钟。然后好容易把结果输出,把它从一堆不相关的内容里找出来又花去半天;最后为将内容整理有序又花去大量精力,接着才能进入正式的分析环节。每次都是一种九九八十一难的错觉。
3.2 构建安全防护网
针对常见的高频,反复出现的系统问题,以及梳理出的系统热点调用API,补充完善相应的测试用例,逐步构建安全防护网。
中心指导思想就是尽早发现问题,降低错误修复成本。
注:这里的测试用例只是代称,不要在乎形式:单元测试,bat脚本,postman脚本都行,唯一要求是方便持续集成。
3.3 文档化
纵观百余年来的软件开发史,商用软件以及开源软件绑在一起,称得上文档完善的,凤毛麟角。
如果某个软件产品让各方诸多抱怨,那么文档缺失一定属于其中之一。
作为空降系,我们首先需要的是熟悉既有技术架构,去了解当前技术架构背景下,各类问题的解决方案,之后才能进行针对性地优化。
当前技术架构经过多轮迭代,人员更迭,当初做的技术决策已经成了无头案。我们需要从当下开始,将眼前这个各方不满意的技术架构内部的实现全部摆出来,放在太阳底下。
- 文档化有助于当事人快速熟悉现有技术架构。
- 文档化有助于建立起团队内部知识共享,传承,减少沟通成本。
- 文档花有助于降低团队对于当前技术架构的不安感。毕竟只有对于一件事全貌了解,人们才能更放心地面对它。
关于文档化,有些关键点需要注意下:
- 以身作则。团队当前肯定是不具备文档化氛围(不然问题不会积攒到这么大),这样的背景下,身先士卒的表率有助于减少推进的阻力。
- 针对当前技术架构中各类问题的解决方案,以专题的形式进行分类汇总到一起。例如数据库查询有了哪几种实现,日志记录又有哪几种实现,是否有着某些魔法操作需要注意等等 。以专题形式建立起的这些文档,有助于之后问题的集中讨论和针对性解决,实现解决方案的统一。毕竟很少有因为技术栈统一导致的问题,往往都是因为缺乏检查和管理,造成同一类问题出现多种技术实现,进而导致系统维护成本高,漏洞如红绿灯一样始终没法完全堵住。
3.4 DEVOPS
这里我们只是想借助DEVOPS核心思想里的"标准化,自动化,自主化"来说明些问题。
作为一项工程,软件研发很少有因为存在技术瓶颈导致失败的。相反,沟通难,沟通成本高等问题才是焦油坑一再出现的主要原因。
每次出现问题时,团队内部各岗位之间对于问题理解不一致,需要反复磨合确认才能拉平各方认知,然后才开始进入问题解决环节。排错五分钟,定位两小时的情景屡见不鲜。
"标准化,自动化"的思想要求我们尽量减少不必要的沟通,能够不让人工参与的操作就要绝对避免人工介入。能够形成团队规范公开的,就不要私下商量一堆暗语。
自主化的典型例子就是“谁开发 谁运维”,问题的解决路径要尽可能地短。
3.5 重构
最后让我们来谈点直接代码层面上的。
首先我们要明确,我们接下来要做的是重构,而不是重写。
其次遵从“奥卡姆剃刀原理(如无必要,勿增实体)”。如果为了解决某个问题需要引入新的依赖项,那么先做减法,再考虑加法。
- . 引入一个新流程前,先去掉现有的一个流程。
- . 引入一个组件前,先去掉现有的一个组件。
再次则是统一技术栈。架构中引入多种解决方案的不良后果之一就是出错原因增多,系统维护成本高。
4. 保持耐心
专门作为一个小节来强调这一点,是因为见证了不少热血上头的改革派,头脑发热地直接奔着问题冲上去,然后迅速在残酷的现实打击下一蹶不振。
冰冻三次非一日之寒,现在所面临的问题不是一天内造成的,你就不能奢望一天内就能药到病除。
好事多磨,磨难不该被追求,但在追求美好的道路上一定是布满艰辛。
5. 事和人
对于既有产品技术架构的升级改造这件事,人是最终决定因素。
软件产品有问题,本质反映的还是既有团队存在问题。
作为外来者,你还是需要先做事,通过解决问题了解情况,同时也是证明实力来增加信任,有了信任之后事情就好办了。
6. 参考
- 传统软件行业中技术团队的发展 - 做好技术栈统一
- 传统软件行业技术团队中如何做好知识沉淀