敏捷与 DevOps 成熟度模型
领域/级别 | 1(基础) | 2(入门) | 3(中等) | 4(高级) | 5(专家) |
---|---|---|---|---|---|
敏捷 | 需求池 迭代计划会议 迭代评审会议 在线项目管理 |
故事点 每日站会 跨职能团队 面对面沟通 企业通讯软件 |
敏捷教练 公共知识库 迭代反思会议 远程视频会议 企业通讯软件机器人 |
完全掌握 Scrum 远程办公实时沟通 融合极限编程等框架 |
PMO 规模化敏捷 敏捷式办公室设计 |
架构 | IaaS 云服务器 静态网站架构 使用域名提供服务 HTTPS 与 no-www |
PaaS 数据库 使用合法域名 研发掌控服务器 测试/生产环境一致 |
容器化 PaaS 图片处理 SaaS 持续集成 本地/生产环境接近 |
容器集群 PaaS 100% SaaS 代码托管 秒加字段数据库 |
微服务 自动伸缩 Serverless SaaS 100% |
代码与测试 | 多分支开发 提交信息标准化 自动检查代码规范 先进的版本控制系统 |
原子性提交 Code Review 代码关联事项 人工测试在线管理 |
使用持续集成 自动化单元测试 自动化集成测试 测试行覆盖率达 50% |
代码静态分析 自动化性能测试 自动化安全测试 测试行覆盖率达 80% |
动态测试覆盖率分析 测试驱动开发(TDD) 自动化端到端回归测试 测试行覆盖率达 90% |
持续交付 | 提交自动触发 自动部署到单一环境 SSH 和云存储自动部署 数据库变更纳入代码库 |
部署到不同环境 配置与代码分离 自动变更数据库 |
交付为制品 代码 tag 即版本 数据库变更可回滚 事先交付 API 文档 |
上线不停服 事先交付 Mock API |
蓝绿/金丝雀部署 自动部署到生产环境 |
告警与反馈 | 宕机响应 业务宕机直达研发 服务器告警直达研发 |
开发人员掌控 Log 采集 服务器分布式 Log 采集 基于统计排查 500 错误 |
前端用户反馈 故障分级响应 容器 Log 采集 业务 Log 标准化 业务报错直达研发 |
数据可视化 前端错误采集 前端统计分析 第三方前端反馈 数据库监控和优化 |
SLA APM A/B 测试 数据实时可视化 实时服务状态报告 |
敏捷
-
传统瀑布模式,有以下三方面的缺点:
①研发周期过长,导致研发跟不上业务发展的节奏。在瀑布模型中,所有的工作都是串行的,只有前序环节完成后,才能展开后序环节。
②研发过程无法及时响应需求变化,直至项目结束的最后一刻才向客户一次性交付产品,很可能与客户的预期不符导致满意度下降。
③不能很好地管控风险。这是因为研发到最后才一次性交付产品,所以项目中很多风险在前期很难被完全识别出来。团队逐步替换掉瀑布模式,从使用迭代(Sprint)开始。
建立需求池,开展迭代计划会议(Sprint Planning Meeting)与迭代评审会议(Retrospective Meeting)。前者按照用户价值来描述需求,并对需求池里的 backlog 进行优先级排序;后者展示迭代工作结果,产品负责人给出评价和反馈,以用户故事是否能成功交付来评价完成情况。了解敏捷。敏捷 = 价值观(敏捷宣言) + 原则(12 条原则) + 一系列符合价值观和原则的方法与实践。了解传统的瀑布模式与敏捷的区别。 使用在线的项目管理工具,方便项目过程中的记录与沟通协作。
提交的代码能与事项关联,做到工作过程的可定义和可记录。 -
组建跨职能团队。
跨职能团队的成员来自公司不同职能领域的人,不仅有技术专家,还应包括业务分析师或其他积极参与项目的人员。
使用企业即时通讯软件(Enterprise Instant Messaging)替代个人即时通讯软件,比如企业微信、钉钉、Slack 等,支持跨平台、所有历史消息可同步可检索。
使用面对面沟通替代文档沟通,这是对瀑布式项目历史的一种反应,瀑布式项目严重依赖文档化的需求,而向项目团队传递信息的最有效方法是面对面交谈。
团队内开每日站会(Standup Meeting),总结今天的任务完成情况、交流遇到的困难,以及计划明天的安排。采用故事点评估法,从而形成可持续的良好工作节奏。传统软件团队使用时间估算工作量,但敏捷团队使用故事点估算软件规模。比较受欢迎的估算方法包括:计划扑克(Planning Poker)、T - 恤尺寸(T-shirt size)、点投票(Dot Vote)等等。
-
使用企业即时通讯软件的自动化扩展。
比如大部分 EIM 内置了自定义机器人部署功能,能够自动发送服务故障报警,高效融合聊天与操作后称之为 ChatOps。
在需要远程会议时,使用远程视频沟通。
团队分配角色,开始有敏捷教练(ScrumMaster),负责指导并维护团队内的敏捷秩序。
加入迭代反思会议(Retrospective Meeting),总结哪些事情做得好,哪些事情做得不好。会议得出这样的结论:开始做什么、继续做什么、停止做什么。
积累公共知识库,鼓励团队内部相互学习交流,积淀通用知识。 -
完全掌握 Scrum,严格遵守约束条件。
“三三五五”:3 个角色(产品负责人、团队、ScrumMaster),3 个工件 (产品待办事项列表、迭代待办事项列表、产品增量),5 个事件(Sprint、Sprint 计划会议、每日 Scrum 站会、Sprint 评审会议、Sprint 回顾会议),5 个价值(承诺 、专注、开放、尊重、勇气)。
根据团队实际情况,融合极限编程等框架,比如在引导新人融入团队时,采用结对编程。
通过基础建设,实现工作时间内的远程办公实时视频沟通。 -
设立敏捷组织里的项目管理办公室,即 PMO (Project Management Office)。
在组织架构的设计上建立体系,将 PMO 作为实践的保护者和支持者,负责在组织内实施和扩大敏捷实践。一般来说,任何 PMO 都有责任去最大化组织内部项目组合的投资回报率。在办公室设计、装修以及环境布置上下功夫,目标就是为开展敏捷实践提供最大的方便。比如整个办公区域是完全开放式的,方便进行可视化管理;设计足够长、足够大、没有挡板和隔断的办公桌,有利于每天的结对编程和 Code Review。
在大型公司里,可以先设立几个敏捷试点团队,顺利之后做规模化推广。
规模化推广不等于直接复制试点经验,比如一旦小团队的数量多于两个,就会牵涉到团队与团队之间的协同问题;又比如在多个团队一起开发同一个产品的情况下,又会涉及到团队间的管理问题。
敏捷的规模化推广,当前有两个主流的框架,SaFe(Scaled Agile Framework)和 LeSS(Large Scale Scrum)。
总结有以下 5 个要点:
①选择合适的规模化推广策略。
②做好敏捷文化铺垫,培养好敏捷的中坚力量。
③搭建适合敏捷的工作环境,做好必要的工具和自动化准备。
④组织级别的敏捷度量以及持续改进。
⑤重视大型团队的敏捷导入与推广。
架构
-
还在使用物理服务器,运维工作量大,无法实现运维开发一体化,影响开发效率;邮箱等 SaaS 未配自定义域名,影响员工办公效率;静态网站架构错误,占用了服务器;往往也存在一些技术问题:使用 IP 提供 web 服务、未开启 HTTPS、no-www 无法访问。
经过培训学习,了解了 IaaS 虚拟化,放弃物理机改用公网云服务器,或者购买私有云解决方案。此时一般不了解 PaaS 云数据库,难以推动,所以先从静态网站架构入手,掌握云存储和 CDN 架构,使用域名提供服务,开启「强制 HTTPS」,www 和 no-www 都能访问,二选一进行跳转,达到基本的用户体验。
-
用了云服务器,但可能还在自建数据库,未使用 PaaS 数据库,导致运维成本和数据丢失风险;测试与生产环境的架构不一致,导致难以在测试环境发现隐患;开发人员没有权限操作服务器和域名解析,而是不懂技术的人在管理,导致违规使用域名和 IP(比如 dl_dir.qq.com、oa.com、1.1.1.1)、跨部门申请效率低下、开发人员对服务器没有认知,难以排查线上故障,难以养成对线上服务负责的态度。
经过培训学习,用上了 PaaS 数据库、Redis 等中间件,运维的工作量降到几乎为 0,开发人员直接在云计算界面点击即可开通服务器/数据库等产品、配置域名解析,可以快速创建自己需要的测试环境,做到测试与生产环境的架构一致,此时自然也不再违规使用域名和 IP。
-
做到了上面的要求,服务器架构仍然不佳,多个项目无法部署到同一台虚拟服务器上,因为存在依赖冲突、端口冲突,结果每个项目都需要购买一台服务器,浪费了资金;自建的技术工具维护成本高,比如 持续集成/部署。
经过培训学习,采用容器化或 Serverless,正好在这种架构下,用户上传的文件无处存放,应采用云存储,也就有了 PaaS 图片/视频处理,不需要自己开发了;使用容器技术,本地开发环境也能更方便的搭建,开发人员的本地环境应尽量和生产环境接近,比如服务器是 Linux,本地应使用 Linux/macOS,考虑到成本和图形界面稳定性,推荐 Windows 用户使用 Windows Subsystem for Linux(WSL)。小公司小网站采用单台服务器也能达到此评级,达到优秀的技术体验、安全可靠和低廉的维护成本。
-
上一步采用单点 Docker 难以管理,不够可靠;用户上传文件到后端,占用带宽,降低了用户体验,浪费了资金,无法重用轮子;代码托管、招聘、CRM 等仍在使用自研自建,未使用 SaaS,开发维护成本高、无人升级维护,逐渐技术落后、交互体验差,降低了大家的工作效率。
经过培训学习,采用 PaaS K8s 等容器集群管理工具、前端上传、SaaS。托管 K8s 支持单台服务器,但对配置要求较高(2c2g、负载均衡),做政企等低访问量网站的外包公司可能不需要这种架构,所以达不到这种评级,这也合理,我们不能给专做小网站的外包公司架构评分很高,那样会误导大众觉得这公司能做大项目。
-
经过上一步的 SaaS 化,公司的内网服务降到很低,但还是残存一些内网服务,导致远程或移动办公时,需要接入公司 VPN,面临卡顿崩溃等问题,降低了工作效率。还存在一些问题:流量增大时服务器无法自动扩容,流量降低时无法缩容;项目越来越大,难以维护。
经过培训学习,掌握了自动伸缩、微服务,内网服务全部改成公网或 SaaS,使用「端口敲门」等技术取代 VPN。
代码与测试
-
初级阶段可能在使用 SVN 等落后的版本控制系统;采用主干开发,多人提交易产生冲突;未采用业界知名的代码书写规范,或虽有规范但无法强制执行;代码提交信息各人随意填写,未采用知名规范。
经过培训学习,使用先进的版本控制系统(比如 Git),锁定主干,使用多分支开发流程(如 Master Flow、Simplified Git Flow),使用业界知名的代码书写规范,本地提交代码时自动且强制检查代码规范,使用业界知名的代码提交规范(Angular Git Commit Guidelines)和工具(Git Commitizen)。
-
上一步采用了多分支开发流程,但没开展 Code Review,大家往往直接同意合并,还存在一些错误做法:一次提交上千行代码,别人难以理解、提交了编译/构建的结果(比如 apk、jar、压缩后的 CSS/JS)、提交了依赖的第三方库(比如小程序初期不支持 npm、需要修改第三方包而不知如何下手)。人工测试缺乏信息化管理,发生遗漏。
经过培训学习,在每次提交时进行 Code Review,确保团队做到:原子性提交、不提交编译/构建的结果,不提交依赖的第三方库(使用 npm/composer 网络安装),掌握修改第三方库的方法(patch 或 fork 改名再发布),静态库使用公共 CDN(比如 Google Hosted Libraries、StaticFile.org),代码关联事项 ID,让代码库变得干净。使用在线的测试管理工具,对测试用例进行管理和评审,按计划执行测试,生成测试报告。
-
上一步清理了项目,开展了 Code Review,但人眼难以发现逻辑错误。随着项目的发展,功能和代码量越来越多,人工测试耗时越来越长,人力成本越来越高。
经过培训学习,由开发人员写测试代码,和业务代码一起提交,在持续集成中自动运行单元测试和集成测试,如果失败则禁止合并。核心代码先进行自动化测试,行覆盖率达到 50%,节约了一部分测试的人力成本。
-
上一步给部分代码进行了自动化测试,但 50% 是远远不够的,人工测试的工作量仍然很大,线上故障频发。
经过培训学习,自动化测试行覆盖率达 80%,团队只保留少量的人工测试负责难以自动化的界面测试;开展自动化的性能和安全测试;除了代码规范检查以外,使用更多的静态分析工具。
-
在提高测试覆盖率的过程中,可能发现:业务代码写完了,但不可测。
经过培训学习,掌握测试驱动开发(TDD),彻底解决代码不可测问题,把覆盖率提高到 90% 甚至 100%;每次合并时动态分析测试覆盖率,如果覆盖率下降,原则上不允许合并;开展自动化端到端回归测试。
持续交付
-
不了解自动化部署时,往往通过手动部署,比如 FTP、SCP、SSH 拉代码,有「DRY」意识的工程师可能写了脚本,都不够自动和标准化;修改数据库字段没有脚本化,没有纳入代码库,导致难以追溯。
经过培训学习,掌握了「持续部署」系统的基本用法,提交代码时自动触发部署,比如常见的后端通过 SSH 部署到 Linux 服务器、前端部署到云存储。由于刚入门,不熟悉,先自动部署到单一环境,比如测试环境。
-
尝试过自动部署,感受到了便捷性,希望按规则部署到不同环境,但代码里往往固化了数据库地址等配置,难以适应不同环境;手动执行数据库变更脚本,导致各个环境数据库字段不一致。
经过培训学习,把配置与代码分离,放在环境变量中;部署时自动变更数据库,确保各个环境数据库字段一致;能够部署到不同环境,比如自动部署到测试环境,手动触发部署到生产环境。
-
每次部署都重新构建,不能确保各个环境的代码一致,可能出现「测试环境没问题,线上却有问题」的情况;项目没有版本,出问题时只能回归到某个提交,难以操作,容易出错;数据库变更无法回滚,导致线上故障无法及时回滚、本地测试无法顺利进行;前端工程师等待后端开发完毕提供 API 文档。
经过培训学习,掌握了「持续交付」——构建为制品,保存起来,一次构建到处部署,确保各个环境的代码一致;使用代码库的 tag 用于版本,遵守「语意化版本」规范;数据库变更可回滚;在后端开发之前,先设计并交付 API 文档给前端工程师,提高了效率。
-
前面实现了部署时自动变更数据库,但数据量大时会卡死,导致服务中断。
经过培训学习,采用秒加字段数据库(如 MySQL 8.0)等架构技术,实现上线不停服;使用 Mock API,进一步提高前后端协作效率。
-
上一步实现了上线不停服,但导致上线后才发现故障。
经过培训学习,使用蓝绿/金丝雀等部署策略进行验证,实现放心的自动部署到生产环境。
告警与反馈
-
初期没有监控告警机制,服务器的 CPU/内存/硬盘满载宕机,业务宕机都无人知晓。
经过培训学习,在云计算网页控制台开通服务器资源和业务调用(如 HTTP 请求)的短信/电话实时提醒,直接发送给开发人员,实现基本的宕机响应。
-
上一步把告警信息直接发送给了开发人员,但开发人员如果没有服务器权限,会导致无从下手,浪费宝贵的抢修时间。在架构 2 级实现了开发人员掌控服务器,解决了这个问题。但还存在一些问题:运维人员配置了 Log 采集,开发人员对 Log 不熟悉不重视。
经过培训学习,改为开发人员掌控 Log 采集,自行配置,自然熟悉起来;掌握业界成熟的分布式采集程序;使用统计程序,排查出现次数多的 500 错误。
-
上一步使用服务器 Log 排查错误会面临上下文数据不足的问题;此时架构也升级到了容器化,Log 文件无处存放;用户发现问题时,无处反馈,只能发微博/打电话。
经过培训学习,在业务代码中加入 Log,遵守业界通用的级别定义的格式,便于排查问题和采集;业务出现 error 级别错误直接通知到开发人员,warning 通过采集汇总,也就需要制定故障分级响应机制;掌握容器 Log 机制——输出到 stdout/stderr;在前端加入反馈功能,方便用户反馈。
-
上一步在前端加入了反馈功能,如果是自己开发的,业务宕机时反馈功能也无法使用,所以应使用第三方;随时用户量/业务量的增长,服务变慢,而不知道原因;前端报错没有采集,也缺乏用户行为分析。
经过培训学习,掌握了数据库的慢查询等性能监控和优化方法;使用第三方前端反馈;对前端进行统计分析和错误采集。
-
新版上线之后,通过前端统计分析发现效果不如旧版,为时已晚;线上数据量往往无法在测试环境完全模拟,出现性能问题,难以排查。
经过培训学习,掌握了 A/B 测试,对新版和旧版的数据进行对比,当然这也需要架构层面的支持;在线上引入 APM,排查性能问题;对外实时输出服务状态报告,承诺 SLA。