淘宝出了本书《交付之道》,没来得及看(有时间一定)。不过文中内容应该是和我的工作认知是匹配的,这里就先瞎扒拉扒拉我想到的一点内容。
以我的理解
对于业务系统,技术和代码都是以增加功能、解决问题、创造收益为目标。这么来看,甲方应该应该是业务和PM,交货的是「需求」;技术需求也是类似的。围绕着需求,交付之道就是保障需求的各个阶段顺利进行:提出、开发、测试、上线、结果等。
上线前
明确需求
由PM提出产品需求、由RD提出技术需求,此阶段重点在于判断需求合理性和目标,以及排优先级。前者是大家老生常谈的业务SENSE和要收益。后者是面对过载的需求,所必须要做的人力管理。
关于需求,我想到:
- 对于产品需求,慢慢演变成“RD只是工具、做就完了”的现状。尤其是在这RD说不上话的GEC,虽然吐槽没啥收益的专项满天飞,但也都得做。反转一下:之前我也是觉得大部分需求都在做无用功,但是最近看书后对于“快速迭代、AB实验、错了就换”感受非凡,书中也讲了很多案例和方法论,和曾经接触过的需求和思路遥相呼应。所以对于需求的合理性和目标,自己认知里的也不一定正确,还是更多学习学习产品思维的。
- 技术学院推出「飞书文档投稿」功能时,我一百个反对,不理解为什么已经有了「markdown投稿」还要新增投稿方式?结果「飞书文档投稿」大受RD喜爱,投稿量翻几番。这其实就是命中了「渠道—产品匹配」。
- 对于技术需求,其实很多项目就是大家所吐槽的瞎卷,尤其是涉及到想扩大自己影响力scope的,典型就是营销C天天想推的营销展示组件化。不过也有很好的技术功能,曾听到一个PM大力夸赞阿里的黄金令箭(自动埋点、分析数据来源、价格一致监控、参数一致监控)。不过无论技术需求的合理性和目标是什么,重要的是对齐LD的态度。
多团队协作
大型项目都是需要多个团队参与的,而协作的本质是多个团队之间对齐目标和排期。
- 业务需求其实也算是PM和RD之间的对齐,现在是通过定容机制保障双方友好协商、顺利启动需求。想起杨光伟说的“PM、RD本该是一家,大家要一起努力,但是现在RD天天喊着没人力、和PM不对付,非常的别扭”——是这样的,越是换到复杂的团队,越是这个感受。
- 需求专项业务专项,通常是多个PM团队先对齐目标,再各自和对应的RD对齐(定容)。
- 自上而下的技术需求是老板拍板,自下而上的技术需求是说服老板来拍板。不过都是组内的项目,对齐(做或不做)是比较简单的。
- 比较难的是外团队推动本方做配合型的技术大变更。很大的一个考虑点是:做这个事情对我有什么收益。卢俊谈技术规划时说到4个O中有3个是配合其他团队(OKR),这是对自己和团队的认知不清。由本方推动外部团队一起合作做某件事,其实也是一样难受的,因为很难搞出一个对双方都有益处的轮子。而营销C的技术需求,现在常常是这两类事。
方案设计
技术方案应包含:项目背景、项目相关信息、整体方案概述、架构和链路、具体实现、稳定性相关、测试建议、上线流程。具体实现中有更细粒度的设计,如存储设计、IDL设计、链路变更等。团队可以搞几个技术方案模版,RD上手就会比较简单,例如:xxx,yyy。但是对于模版的使用,大多数人都是直接全部copy,我不喜欢这个行为,因为模版中很多内容都是冗余的,copy到技术方案文档就变成完全无效或不相干的内容,只会留下大量空荡荡的标题。
需求或方案,无论是简单还是复杂,都应该出个技术方案。一是用于记录,以便评审和review。二是在必要时可以跳过看代码直接了解逻辑,这就引出一个问题:要保证方案和代码是完全匹配的,尤其是变更方案后要记得同步在文档中。
另外,写技术方案很重要的一点是为了评审和讨论。但是据我观察,很多团队都在逐渐弱化这个过程:需求来了,有个人承接做完就行了,其他人也不知道他具体是怎么做的。
开发
方案设计可以对应上《整洁架构之道》,代码开发就可以对应《代码整洁之道》。程序员首当其冲的素养还是要能够写出好的代码啊。
关于如何写代码,我的观点一直是“要写出「简单好懂」的代码”,我也时常疑惑为什么一个字段打包逻辑能写出上千行代码。
- 简单逻辑简单实现即可,不要套上复杂的框架、设计模式等
- 复杂逻辑,包括复杂的业务逻辑,要争取实现成清晰有条理的、可扩展性的、易测试和排查问题的;
- 注意代码执行效率,比如循环次数、拷贝次数、使用更合理的数据结构等
当然,开发除了写代码外,还有很多其他内容,比如:
-
代码分支
- 开发前,保证当前代码是「匹配」线上master的
- 在需求开发时,可以避免产生代码冲突
- 在代码迁移时,可以避免遗漏线上代码。刚出的事故主责是:在迁移交易侧代码时(交易营销链路治理项目),在十月份时开发、但是基于九月份的代码版本,从而遗漏了九月底上线的需求。
- 也不要随意使用或基于其他分支进行开发
- 上线MR建议自己先 review 一次,再去找其他同事AP
- 开发前,保证当前代码是「匹配」线上master的
-
代码风格
- 建议是使用线上现成的逻辑和风格,而不是非要重新搞一套格格不入的(属于自己的)特殊风格。尤其是新Landing的同学,容易被喷。
-
IDL设计
- 只能进行兼容性的变更;
- 若必须要破坏性的变更,需要周知到所有使用方;但是即便是周知到使用方,如何合理地顺序上线也是个大麻烦,所以还是遵循第一点;
-
等等...(想到的时候再补充)
测试
最近的一次事故又深刻体会到“设计过程中要考虑可测试性(软件设计之美)”这句话的含金量。无论是业务需求还是技术变更,进行逻辑变更后,肯定是需要对该逻辑的输出进行测试。因此在技术评审和测试用例评审时,应该多考虑如何对输出内容进行测试。
事故的部分原因是因为漏测:某第三方数据未在接口response返回,直接落DB,因此DIFF工具无法检测出问题。QA认为这是第三方数据,因此仅测试写DB是否成功,没有校验数据正确性;RD也没有考虑该数据的可测试性。
考虑可测试性这点,课代表应是单元测试和自动化测试:
- 单元测试
- 编写测试时,可以从外部视角看待代码,这让我们看起来是代码的客户,而不是代码的作者。如果感觉难受,那么很可能是因为在代码设计的时候,并没有把“容易测试”考虑进去,可测试性不强。
- 操作上可以通过git hook进行自动触发,对比函数输出是否符合预期。
- 自动化测试
- 字节的tesla:QA通常会创建长期存在的物料,然后在脚本中使用物料调用接口,并分析接口结果是否符合预期。
其他我所接触过的测试方式:
-
QA测试,需求必备
- 包含页面用户行为、接口逻辑和response返回、存储数据正确性
- 在测试前,一般还有研发自测(冒烟CASE)+showcase,减少bug和提升测试效率
-
数据DIFF对比,尤其在重构和大技术变更的项目中需要
- 最简单的就是新旧逻辑同时执行,写段硬编码进行数据对比和打点
- 字节的FTF工具,可以抓取线上流量在PPE重放并对比response,然后提供界面化供RD和QA标注diff结果
- 在summary重构时,和赵老板一起搞了个在线流式DIFF工具,有实时采样对比、diff率分析、重刷diff等功能
-
压测
- 对于存在较大流量变化的变更,需要评估+测试资源问题,包括DB、cache、服务cpu
-
小流量的“众包用户”体验
- Launch preview
- 常见到各种APP邀请用户去体验新版本或新功能
- 重大功能或变更上线后,比如大促玩法,在功能完全开放前,会提前开放给一部分用户进行体验
看到个事故参考文档,里面介绍了风险源和对策,我觉得刚好是对应了各种变更的测试方式:
//图略
上线中
回归
主要是保障线上核心功能不被本次上线所影响,比如
- 抖音电商每周三进行客户端发版,因此每周五会召集QA对下周新版本进行回归,包含本周新增的重点功能、线上核心功能、P0用户操作。
- 对于火车发布部署模式,在火车冻结阶段,验证P00用例
上线流程
上线流程一般按团队规范、服务量级、研发现状等条件而定,不过流程如何都无所谓吧,关键是保障上线时的稳定性和上线效率。使用过的上线流程有:
-
国内电商时:需求测试完成后,MR先合入master,再master分支上线。为了避免多需求上线冲突,会有搭车现象,比如两个需求MR都合入master后,再由一个人进行上线。
- 存在的问题:代码revert不方便;需求上线难以管理。
- 优点:效率高,灵活性强。
-
国际化电商时:火车机制,一趟火车生成一个上线分支,需求MR作为车票,合入上线分支。最终由火车上线分支带着多个车票进行上线,上线完成后火车上线分支再合master。
- 存在的问题:上线分支有未合master的风险;同时进行的火车存在上线覆盖;需求车票相互耦合。
- 优点:便于管控。
上线流程还包括:
-
明确上线顺序,以保障服务的依赖正确
- 所依赖的服务和配置需要先上线
- 开发阶段的依赖,在上线前判断是否还需要更新,比如overpass、sdk
-
对于第一次上线的新服务,要关注服务配置的正确
- psm、端口、机房、环境变量等;
- cpu/内存是否合理;
稳定性保障
- 分阶段发布,比如小流量、单机房、全机房三阶段发布
- 需要较长时间去观察各个阶段的监控:AB指标对比,日常报警(成功率、错误量、错误率),日志变化,业务大盘,自定义功能埋点指标(cache的miss/hit监控、DB慢查询)
上线后
监控
上线中一定是需要基于监控来观察本次上线是否存在风险。但是并非上线时监控无异常就代表不存在问题,所以日常(上线后)也要持续关注监控。主要是服务指标和业务指标。
- 服务指标可以每周进行观测和对比,即主动防劣化分析。
- 业务指标可以间接地发现问题,遇到过两三次是业务oncall反馈GMV下跌,最终定位bug。对于这种指标得思考下如何转换为服务指标进行观测。
回滚
-
若在上线期间发现问题,建议直接回滚
-
若在上线后发现问题,可以先判断影响面,再决策回滚
- 难点在于发现问题,并关联到是由某次上线引起的。国内电商的SRE和TCE做了个平台,可以搜索每个服务、每段时间的发布动作。
- 对于影响面,建议拉更多人来一起判断
-
注意:操作回滚时,一定要保证回滚行为有效和正确
- 最近有个事故,由于流水线Bytecycle导致回滚慢、扩大了影响面。因为海外有i18、ttp、eu多面板,流水线也变得非常复杂,一个发布流水线会关联上多个子发布流水线,因此流水线本身的稳定性降低,从而会引发一些发布混乱。另外由于海外权限问题,流水线上无法直接操作回滚。
oncall
任何业务任何部门都难以避免oncall:一种是bug引发用户产生问题,一种是用户自以为是出了问题。本质上都是基于现状排查问题,这里的重点在于易排查性和排查效率。前者大概率是依赖于当前实现,在营销标签重构时,我在架构里加入了标签生产过程跟踪标记,虽然是很简单的逻辑和代码,但是让标签生产全过程一目了然。后者,有可能是当前实现导致问题排查难度大、有可能是排查人对现状不了解导致排查速度慢、有可能是无法复现导致排查无法下手,我认为这几点都是需要团队或owner多思考多考虑如何解决的。
额外提一下,对于中台或平台来说,现在通过oncall来咨询问题的情况也越来越多。实际上也是非常消耗人的,是需要提效的。
结果回收
「研发提升业务SENSE」的相关文章中,都有提到要确认需求上线之后的效果和数据。
- 业务效果,如 DAU、MAU、活动参与人数、订单数、成交量、成交额和运营效率等。
- 系统效果,如峰值 TPS、接口性能、响应时间、崩溃率、可用性、成本和开发效率等。
更详细的话,就是写一篇项目总结或复盘的文档,包含技术方案、实现过程、收益和结果、问题和思考等。
在回收结果或总结的过程中,其实能学习到很多业务知识(关注点重点和现状数据)和产品思维。比如某个业务某个功能为什么用GMV来衡量、这个需求为什么不做实验。
其他
对事故要保持敬畏
- 首先,要以重视的态度去判断问题发生&发现后的影响面。重点要及时同步,再根据定级(优先级)进行处理。有时候不同视角对影响面、事故等级的判断是不同的,因此发现问题后,「及时和mentor+LD+QA沟通」很重要。
- 回过头看,要在方案设计和实现时,就要怀揣着「不出问题」去考虑各个功能细节、各个阶段、各个实现。不要偷懒,尤其是越大的需求越要谨慎和合规。就个人利益来讲,事故出现后,超多LD开始关注、开始了解发生原因、开始review需求开展合理性,这时候要是有“小辫子”被抓到,就很惨。当然需求做得越谨慎越合规,自然出问题的风险就越小。
做需求的态度
看书《交付之道》
TODO