敏捷与 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 测试
数据实时可视化
实时服务状态报告

敏捷

  1. 传统瀑布模式,有以下三方面的缺点:
    ①研发周期过长,导致研发跟不上业务发展的节奏。在瀑布模型中,所有的工作都是串行的,只有前序环节完成后,才能展开后序环节。
    ②研发过程无法及时响应需求变化,直至项目结束的最后一刻才向客户一次性交付产品,很可能与客户的预期不符导致满意度下降。
    ③不能很好地管控风险。这是因为研发到最后才一次性交付产品,所以项目中很多风险在前期很难被完全识别出来。

    团队逐步替换掉瀑布模式,从使用迭代(Sprint)开始。
    建立需求池,开展迭代计划会议(Sprint Planning Meeting)与迭代评审会议(Retrospective Meeting)。前者按照用户价值来描述需求,并对需求池里的 backlog 进行优先级排序;后者展示迭代工作结果,产品负责人给出评价和反馈,以用户故事是否能成功交付来评价完成情况。

    了解敏捷。敏捷 = 价值观(敏捷宣言) + 原则(12 条原则) + 一系列符合价值观和原则的方法与实践。了解传统的瀑布模式与敏捷的区别。 使用在线的项目管理工具,方便项目过程中的记录与沟通协作。
    提交的代码能与事项关联,做到工作过程的可定义和可记录。

  2. 组建跨职能团队。
    跨职能团队的成员来自公司不同职能领域的人,不仅有技术专家,还应包括业务分析师或其他积极参与项目的人员。
    使用企业即时通讯软件(Enterprise Instant Messaging)替代个人即时通讯软件,比如企业微信、钉钉、Slack 等,支持跨平台、所有历史消息可同步可检索。
    使用面对面沟通替代文档沟通,这是对瀑布式项目历史的一种反应,瀑布式项目严重依赖文档化的需求,而向项目团队传递信息的最有效方法是面对面交谈。
    团队内开每日站会(Standup Meeting),总结今天的任务完成情况、交流遇到的困难,以及计划明天的安排。

    采用故事点评估法,从而形成可持续的良好工作节奏。传统软件团队使用时间估算工作量,但敏捷团队使用故事点估算软件规模。比较受欢迎的估算方法包括:计划扑克(Planning Poker)、T - 恤尺寸(T-shirt size)、点投票(Dot Vote)等等。

  3. 使用企业即时通讯软件的自动化扩展。
    比如大部分 EIM 内置了自定义机器人部署功能,能够自动发送服务故障报警,高效融合聊天与操作后称之为 ChatOps。
    在需要远程会议时,使用远程视频沟通。
    团队分配角色,开始有敏捷教练(ScrumMaster),负责指导并维护团队内的敏捷秩序。
    加入迭代反思会议(Retrospective Meeting),总结哪些事情做得好,哪些事情做得不好。会议得出这样的结论:开始做什么、继续做什么、停止做什么。
    积累公共知识库,鼓励团队内部相互学习交流,积淀通用知识。

  4. 完全掌握 Scrum,严格遵守约束条件。
    “三三五五”:3 个角色(产品负责人、团队、ScrumMaster),3 个工件 (产品待办事项列表、迭代待办事项列表、产品增量),5 个事件(Sprint、Sprint 计划会议、每日 Scrum 站会、Sprint 评审会议、Sprint 回顾会议),5 个价值(承诺 、专注、开放、尊重、勇气)。
    根据团队实际情况,融合极限编程等框架,比如在引导新人融入团队时,采用结对编程。
    通过基础建设,实现工作时间内的远程办公实时视频沟通。

  5. 设立敏捷组织里的项目管理办公室,即 PMO (Project Management Office)。
    在组织架构的设计上建立体系,将 PMO 作为实践的保护者和支持者,负责在组织内实施和扩大敏捷实践。一般来说,任何 PMO 都有责任去最大化组织内部项目组合的投资回报率。

    在办公室设计、装修以及环境布置上下功夫,目标就是为开展敏捷实践提供最大的方便。比如整个办公区域是完全开放式的,方便进行可视化管理;设计足够长、足够大、没有挡板和隔断的办公桌,有利于每天的结对编程和 Code Review。

    在大型公司里,可以先设立几个敏捷试点团队,顺利之后做规模化推广。
    规模化推广不等于直接复制试点经验,比如一旦小团队的数量多于两个,就会牵涉到团队与团队之间的协同问题;又比如在多个团队一起开发同一个产品的情况下,又会涉及到团队间的管理问题。
    敏捷的规模化推广,当前有两个主流的框架,SaFe(Scaled Agile Framework)和 LeSS(Large Scale Scrum)。
    总结有以下 5 个要点:
    ①选择合适的规模化推广策略。
    ②做好敏捷文化铺垫,培养好敏捷的中坚力量。
    ③搭建适合敏捷的工作环境,做好必要的工具和自动化准备。
    ④组织级别的敏捷度量以及持续改进。
    ⑤重视大型团队的敏捷导入与推广。

架构

  1. 还在使用物理服务器,运维工作量大,无法实现运维开发一体化,影响开发效率;邮箱等 SaaS 未配自定义域名,影响员工办公效率;静态网站架构错误,占用了服务器;往往也存在一些技术问题:使用 IP 提供 web 服务、未开启 HTTPS、no-www 无法访问。

    经过培训学习,了解了 IaaS 虚拟化,放弃物理机改用公网云服务器,或者购买私有云解决方案。此时一般不了解 PaaS 云数据库,难以推动,所以先从静态网站架构入手,掌握云存储和 CDN 架构,使用域名提供服务,开启「强制 HTTPS」,www 和 no-www 都能访问,二选一进行跳转,达到基本的用户体验。

  2. 用了云服务器,但可能还在自建数据库,未使用 PaaS 数据库,导致运维成本和数据丢失风险;测试与生产环境的架构不一致,导致难以在测试环境发现隐患;开发人员没有权限操作服务器和域名解析,而是不懂技术的人在管理,导致违规使用域名和 IP(比如 dl_dir.qq.com、oa.com、1.1.1.1)、跨部门申请效率低下、开发人员对服务器没有认知,难以排查线上故障,难以养成对线上服务负责的态度。

    经过培训学习,用上了 PaaS 数据库、Redis 等中间件,运维的工作量降到几乎为 0,开发人员直接在云计算界面点击即可开通服务器/数据库等产品、配置域名解析,可以快速创建自己需要的测试环境,做到测试与生产环境的架构一致,此时自然也不再违规使用域名和 IP。

  3. 做到了上面的要求,服务器架构仍然不佳,多个项目无法部署到同一台虚拟服务器上,因为存在依赖冲突、端口冲突,结果每个项目都需要购买一台服务器,浪费了资金;自建的技术工具维护成本高,比如 持续集成/部署。

    经过培训学习,采用容器化或 Serverless,正好在这种架构下,用户上传的文件无处存放,应采用云存储,也就有了 PaaS 图片/视频处理,不需要自己开发了;使用容器技术,本地开发环境也能更方便的搭建,开发人员的本地环境应尽量和生产环境接近,比如服务器是 Linux,本地应使用 Linux/macOS,考虑到成本和图形界面稳定性,推荐 Windows 用户使用 Windows Subsystem for Linux(WSL)。小公司小网站采用单台服务器也能达到此评级,达到优秀的技术体验、安全可靠和低廉的维护成本。

  4. 上一步采用单点 Docker 难以管理,不够可靠;用户上传文件到后端,占用带宽,降低了用户体验,浪费了资金,无法重用轮子;代码托管、招聘、CRM 等仍在使用自研自建,未使用 SaaS,开发维护成本高、无人升级维护,逐渐技术落后、交互体验差,降低了大家的工作效率。

    经过培训学习,采用 PaaS K8s 等容器集群管理工具、前端上传、SaaS。托管 K8s 支持单台服务器,但对配置要求较高(2c2g、负载均衡),做政企等低访问量网站的外包公司可能不需要这种架构,所以达不到这种评级,这也合理,我们不能给专做小网站的外包公司架构评分很高,那样会误导大众觉得这公司能做大项目。

  5. 经过上一步的 SaaS 化,公司的内网服务降到很低,但还是残存一些内网服务,导致远程或移动办公时,需要接入公司 VPN,面临卡顿崩溃等问题,降低了工作效率。还存在一些问题:流量增大时服务器无法自动扩容,流量降低时无法缩容;项目越来越大,难以维护。

    经过培训学习,掌握了自动伸缩、微服务,内网服务全部改成公网或 SaaS,使用「端口敲门」等技术取代 VPN。

代码与测试

  1. 初级阶段可能在使用 SVN 等落后的版本控制系统;采用主干开发,多人提交易产生冲突;未采用业界知名的代码书写规范,或虽有规范但无法强制执行;代码提交信息各人随意填写,未采用知名规范。

    经过培训学习,使用先进的版本控制系统(比如 Git),锁定主干,使用多分支开发流程(如 Master Flow、Simplified Git Flow),使用业界知名的代码书写规范,本地提交代码时自动且强制检查代码规范,使用业界知名的代码提交规范(Angular Git Commit Guidelines)和工具(Git Commitizen)。

  2. 上一步采用了多分支开发流程,但没开展 Code Review,大家往往直接同意合并,还存在一些错误做法:一次提交上千行代码,别人难以理解、提交了编译/构建的结果(比如 apk、jar、压缩后的 CSS/JS)、提交了依赖的第三方库(比如小程序初期不支持 npm、需要修改第三方包而不知如何下手)。人工测试缺乏信息化管理,发生遗漏。

    经过培训学习,在每次提交时进行 Code Review,确保团队做到:原子性提交、不提交编译/构建的结果,不提交依赖的第三方库(使用 npm/composer 网络安装),掌握修改第三方库的方法(patch 或 fork 改名再发布),静态库使用公共 CDN(比如 Google Hosted Libraries、StaticFile.org),代码关联事项 ID,让代码库变得干净。使用在线的测试管理工具,对测试用例进行管理和评审,按计划执行测试,生成测试报告。

  3. 上一步清理了项目,开展了 Code Review,但人眼难以发现逻辑错误。随着项目的发展,功能和代码量越来越多,人工测试耗时越来越长,人力成本越来越高。

    经过培训学习,由开发人员写测试代码,和业务代码一起提交,在持续集成中自动运行单元测试和集成测试,如果失败则禁止合并。核心代码先进行自动化测试,行覆盖率达到 50%,节约了一部分测试的人力成本。

  4. 上一步给部分代码进行了自动化测试,但 50% 是远远不够的,人工测试的工作量仍然很大,线上故障频发。

    经过培训学习,自动化测试行覆盖率达 80%,团队只保留少量的人工测试负责难以自动化的界面测试;开展自动化的性能和安全测试;除了代码规范检查以外,使用更多的静态分析工具。

  5. 在提高测试覆盖率的过程中,可能发现:业务代码写完了,但不可测。

    经过培训学习,掌握测试驱动开发(TDD),彻底解决代码不可测问题,把覆盖率提高到 90% 甚至 100%;每次合并时动态分析测试覆盖率,如果覆盖率下降,原则上不允许合并;开展自动化端到端回归测试。

持续交付

  1. 不了解自动化部署时,往往通过手动部署,比如 FTP、SCP、SSH 拉代码,有「DRY」意识的工程师可能写了脚本,都不够自动和标准化;修改数据库字段没有脚本化,没有纳入代码库,导致难以追溯。

    经过培训学习,掌握了「持续部署」系统的基本用法,提交代码时自动触发部署,比如常见的后端通过 SSH 部署到 Linux 服务器、前端部署到云存储。由于刚入门,不熟悉,先自动部署到单一环境,比如测试环境。

  2. 尝试过自动部署,感受到了便捷性,希望按规则部署到不同环境,但代码里往往固化了数据库地址等配置,难以适应不同环境;手动执行数据库变更脚本,导致各个环境数据库字段不一致。

    经过培训学习,把配置与代码分离,放在环境变量中;部署时自动变更数据库,确保各个环境数据库字段一致;能够部署到不同环境,比如自动部署到测试环境,手动触发部署到生产环境。

  3. 每次部署都重新构建,不能确保各个环境的代码一致,可能出现「测试环境没问题,线上却有问题」的情况;项目没有版本,出问题时只能回归到某个提交,难以操作,容易出错;数据库变更无法回滚,导致线上故障无法及时回滚、本地测试无法顺利进行;前端工程师等待后端开发完毕提供 API 文档。

    经过培训学习,掌握了「持续交付」——构建为制品,保存起来,一次构建到处部署,确保各个环境的代码一致;使用代码库的 tag 用于版本,遵守「语意化版本」规范;数据库变更可回滚;在后端开发之前,先设计并交付 API 文档给前端工程师,提高了效率。

  4. 前面实现了部署时自动变更数据库,但数据量大时会卡死,导致服务中断。

    经过培训学习,采用秒加字段数据库(如 MySQL 8.0)等架构技术,实现上线不停服;使用 Mock API,进一步提高前后端协作效率。

  5. 上一步实现了上线不停服,但导致上线后才发现故障。

    经过培训学习,使用蓝绿/金丝雀等部署策略进行验证,实现放心的自动部署到生产环境。

告警与反馈

  1. 初期没有监控告警机制,服务器的 CPU/内存/硬盘满载宕机,业务宕机都无人知晓。

    经过培训学习,在云计算网页控制台开通服务器资源和业务调用(如 HTTP 请求)的短信/电话实时提醒,直接发送给开发人员,实现基本的宕机响应。

  2. 上一步把告警信息直接发送给了开发人员,但开发人员如果没有服务器权限,会导致无从下手,浪费宝贵的抢修时间。在架构 2 级实现了开发人员掌控服务器,解决了这个问题。但还存在一些问题:运维人员配置了 Log 采集,开发人员对 Log 不熟悉不重视。

    经过培训学习,改为开发人员掌控 Log 采集,自行配置,自然熟悉起来;掌握业界成熟的分布式采集程序;使用统计程序,排查出现次数多的 500 错误。

  3. 上一步使用服务器 Log 排查错误会面临上下文数据不足的问题;此时架构也升级到了容器化,Log 文件无处存放;用户发现问题时,无处反馈,只能发微博/打电话。

    经过培训学习,在业务代码中加入 Log,遵守业界通用的级别定义的格式,便于排查问题和采集;业务出现 error 级别错误直接通知到开发人员,warning 通过采集汇总,也就需要制定故障分级响应机制;掌握容器 Log 机制——输出到 stdout/stderr;在前端加入反馈功能,方便用户反馈。

  4. 上一步在前端加入了反馈功能,如果是自己开发的,业务宕机时反馈功能也无法使用,所以应使用第三方;随时用户量/业务量的增长,服务变慢,而不知道原因;前端报错没有采集,也缺乏用户行为分析。

    经过培训学习,掌握了数据库的慢查询等性能监控和优化方法;使用第三方前端反馈;对前端进行统计分析和错误采集。

  5. 新版上线之后,通过前端统计分析发现效果不如旧版,为时已晚;线上数据量往往无法在测试环境完全模拟,出现性能问题,难以排查。

    经过培训学习,掌握了 A/B 测试,对新版和旧版的数据进行对比,当然这也需要架构层面的支持;在线上引入 APM,排查性能问题;对外实时输出服务状态报告,承诺 SLA。