免责声明:本操作手册并非适用于所有的企业,也并非所有的组织都应当按照该流程实施。 —— Phodal
依据我们的实施经验将 DevOps 实施的过程分为了这么几个步骤:
组成部分标题 | 内容 |
---|---|
问题 | 为什么对组织来说引入 DevOps 实践是有好处的? |
成本 | 引入 DevOps 实践的预期成本是什么? |
干系人影响 | 对内部和外部干系人的影响是什么? |
风险和缓解 | 与引入 DevOps 实践相关联的组织和技术风险是什么?如何减缓这些风险? |
推出计划 | 推出 DevOps 的实践计划是什么? |
成功标准 | 我们如何知道 DevOps 实践的引入是成功的 ? |
—— 《DevOps 架构师行动指南》
优先选择优秀的团队?
时间节点-团队-活动-产出表
在 Google ACCELERATE State of DevOps 2019 中有一个基于性能侧的 DevOps 转型策略热图(HEATMAP OF DEVOPS TRANSFORMATION STRATEGIES BY PERFORMANCE PROFILE)
顺带一提,Ledge 已经成为了多个 DevOps 公司的内部资料库的外部参考资源。
供应商锁定通常被定义为“专利锁定或客户锁定,这使得客户依赖于供应商的产品和服务,无法在不产生大量切换成本的情况下使用其他供应商。
咨询公司能从行业内的视野,提供相关的案例,给出更好的建议。
Path to Production,来源于精益,旨在通过可视化的方式来展示项目的上线流程,并优化过程中的瓶颈问题。它类似于我们使用 CI(持续集成)时的 Pipeline。传统的 Pipeline 的 gate 可以通过代码定义一些标准,由测试不能挂,测试覆盖率不能低于多少,打包不能失败等等。而这些 Pipeline 则是分别由开发人员、测试人员、运维人员、项目负责人等等来负责把控的。
对应的,在这个过程中:流程(Process)、人(People)、工具(Tooling)、产物(Artifacts) 都是我们的关注点:
随后,我们从相关的流程中,梳理出每个部分(流程)的持续时间、痛点,来查找优化空间。
示例:
活动 | stage 1 | stage 1 | stage 1 | stage 1 | stage 1 | stage 1 | stage 1 | stage 1 | stage 1 |
---|---|---|---|---|---|---|---|---|---|
流程 | 提交代码 | 运行 CI | 部署到 Dev 环境 | 运行 E2E 测试 | 手动测试 | 部署到 ST/UAT | 手动测试 | 上线申请 | 上线 |
人 | Dev | Dev | Dev | Dev | Dev | 项目 QA | 业务 QA | 业务 QA | PM |
工具 | Git & GitHub | Jenkins | Jenkins | Jenkins | - | Jenkins | - | 邮件 | - |
制品 | 代码 | 持续集成结果 | - | 测试报告 | 测试报告 | - | 邮件结果 | - |
源码管理 | 制品管理 | 配置管理 | 数据库自动化 | 测试 | 持续集成 | 监控 | 分析 | 智能运维 | 协作 |
---|---|---|---|---|---|---|---|---|---|
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
DevOps 流程
DevOps 框架
—— 出自《DevOps 最佳实践》
《持续交付 2.0》中提到了一种不错的软件产品的交付效能度量方式:
简单来说就,就是我们应该从软件的发布模型,倒推出软件的分支策略。
git for-each-ref --format='%(committerdate) %09 %(authorname) %09 %(refname)'
是否拥有构建?
统计:
各个角色组成和人员比例
对于技术债务,它的利息表现为系统的不稳定性,以及由于临时性手段和缺乏合适的设计、文档工作和测试带来的不断攀升的维护成本。 —— 《架构师应该知道的 97 件事》
如 Robert Nord 提出的 “技术债务全景图”(Tech Debt Landscape) 所示:
技术债对于软件的影响:可维护性(Maintainability)、可演进性(Evolvability),而这些技术债对于非技术人员来说都是不可见的。它们源于生活,藏于黑暗中。
来源:《技术债务墙:让技术债务无所遁形)》
在开发代码时你要想想:
如:
目标:以提升能力为核心。
Bruck Tuckman 团队发展模型:
守 -> 破 -> 离
—— 来自《深入核心的敏捷开发》
DevOps 实施看板
组织实施看板
不可构建的系统?
——《Java 持续交付》
常规构建步骤:
9 种遗留系统现代化的技术
发生变化的方面 | Retain | Retire | Encapsulation | Rehost | Replatform | Refactor | Rearchitecture | Rebuild | Repuchase |
---|---|---|---|---|---|---|---|---|---|
产品功能 | No | No | No | No | No | Yes | No | Yes | Yes |
架构 | No | No | Yes | No | Yes | No | Yes | Yes | Yes |
基础设施 | No | No | No | Yes | Yes | No | Yes | Yes | Yes |
代码 | No | No | No | No | Yes | No | Yes | Yes | Yes |
示例:
用户故事评审
估算
方案设计
迭代计划
特性启动
测试用例设计
用户故事启动
测试计划
单元测试
组件测试
用户故事验收
底层测试评审
发布可测试版本
用户故事测试
探索式测试
缺陷管理
风险评估
集成测试
端到端测试
回归测试
发布指南
用户验收测试
发布版本确认
监控
支持
质量分析
见《测试架构师修炼之道》
常见测试类型及其与质量属性关系表
名称 | 说明 | 对应的质量属性 |
---|---|---|
功能测试 | 验证产品能否满足用户特定功能要求并做出正确响应 | 功能性 |
安全性测试 | 验证产品是否有保护数据的能力,并能在合适的范围内承受恶意攻击 | 功能性 |
兼容性测试 | 验证产品是否能够和其他相关产品顺利对接 | 功能性 |
配置测试 | 验证产品是否能够在推荐配置上流畅运行;验证产品为了完成特定功能的输入是否会出现故障 | 功能性,易用性 |
可靠性测试 | 验证产品在长时间运行下能否满足保证系统的性能水平;在存在异常的情况下系统是否依然可靠 | 可靠性 |
易用性测试 | 验证产品是否易于理解、易于学习和易于操作 | 易用性 |
性能测试 | 测试产品提供某项功能时的时间和资源使用情况 | 效率 |
安装测试 | 测试产品能否被正确安装并运行 | 可移植性 |
探索式测试作为系统测试与系统集成测试的补充,执行在手工系统测试和系统集成测试之后。以固定时间窗方式探索系统尝试发现潜在缺陷。
类型 | 说明 |
---|---|
测试类型 | |
测试说明 | |
测试范围 | |
技术 | |
准入标准 | |
准出标准 | |
特殊事项 | |
环境 |
示例:
常见的测试策略组合:
考虑到测试即文档,在实现实现的时候,会配合一些支持自然语言描述的框架,如:
为了与运行客户端一配合,我们还需要有底层 API 来控制浏览器、客户端应用:
工具
工具 | 项目地址 |
---|---|
ApacheBench | https://httpd.apache.org/docs/2.4/programs/ab.html |
wrk | https://github.com/wg/wrk |
Apache JMeter | https://jmeter.apache.org/ |
Locust | https://locust.io/ |
K6 | https://k6.io/ |
Artillery | https://artillery.io/ |
Vegeta | https://github.com/tsenart/vegeta |
对比
工具 | wrk | ab | locust | jmeter |
安装 | 简单 | 简单 | 依赖 python | 依赖 jdk |
场景压测 | 不支持 | 不支持 | 支持 | 支持 |
UI 界面 | 无 | 无 | 有 | 有 |
脚本录制 | 无 | 无 | 无 | 利用本地 ProxyServer 或 badboy |
资源监控 | 无 | 无 | 无 | 通过 JMeterPlugins 插件和 ServerAgent 实现 |
报告分析 | 无 | 无 | 无 | 生成 HTML 报告 |
如我在《系统重构与迁移指南》一书中指出,要给遗留系统项目加测试并不是一件容易的事情。你需要找到对应年代的测试框架,熟悉对应年代的技术栈,然后才能一点点切入系统。
而后,当你遇到诸如 Java 中的 static 方法调用链时,你会发现难以继续往下,便得想着办法重构。而因为没有测试,你又没有办法重构。
实施过程步骤:
来自《持续交付 2.0》的示例:
GoCD 示例:
CI + CD 分离
PS:针对于外部开源请求代码
ng lint --fix
如《架构师修炼之道》的『方法 15:分而治之』所建议的探索案例:
第一周的探索案例:
小组 | 探索任务 | 展示与说明 |
---|---|---|
1 | 重构插件框架,判断原有代码库能否复用 | 展示重构的主要接口和类,说明计划是可行的 |
2 | 尝试 gRPC 服务 | 演示 Ruby 客户端与 Java 服务端的通讯 |
3 | 创建概念图并设计微服务分区 | 展示初步概念图。说明还有这么多工作要做 |
第二周的探索案例:
小组 | 探索任务 | 展示与说明 |
---|---|---|
1 | 通过命令行调用原有插件 | 比预计的工作量多。说明存在哪些障碍,以及计划如何补救 |
2 | 寻找合适的数据库 | 比较三种数据库的优劣(快速浏览其代码) |
3 | 完善概念图,继续设计微服务分区 | 展示概念图和微服务的分区设计 |
如 《DevOps 实施手册:在多级 IT 企业中使用 DevOps》 所介绍的 DevOps 实施方案,几点要求:
结合之下我们有了初步的方案选择:
Nexus 是 Maven 仓库管理器,也可以叫 Maven 的私服。 Nexus 是一个强大的 Maven 仓库管理器,它极大地简化了自己内部仓库的维护和外部仓库的访问。
Verdaccio is a simple, zero-config-required local private npm registry.
阶段 1:规范和标准制定 | 阶段 1.5:现状调研和评估 | 阶段 2.0: 一体化平台调研与规划 | 阶段 2.5:工程教程的赋能 | |
---|---|---|---|---|
目标 | ||||
周期及范围 | ||||
总要举措 | 调研: 规划: 协调: | |||
产出物 | ||||
资源及职责 |
服务级别热力图
代码热力图?
相关文章:
—— 《程序员必读之软件架构》
C4 模型由一系列分层的软件架构图组成,这些架构图用于描述上下文、容器、组件和代码。C4 图的层次结构提供了不同的抽象级别,每种抽象级别都与不同的受众有关。
嗯
-此处应有 C4 图示例-
在设计系统时,组织所交付的方案结构将不可避免地与其沟通结构一致。 —— 梅尔文·康威
构建与目标系统架构相仿的团队结构,这样项目会更容易实现。
事件风暴。它是由 AlbertoBrandolini 提出的,一种用于领域驱动设计的协作设计方法。 事件风暴基于现实业务流程,以系统实现为视角,通过一次只关注一个维度的分层抽象方式,将现实业务流程进行抽象并转化为系统实现的业务逻辑。
它的流程是,通过识别决策命令(decision command)和领域事件(domain event)的聚合(aggregate) or 业务承载物(carrier),并开始将聚合分组到有界上下文中。梳理限界上下文依赖关系,再划分问题子域中。在此过程中,识别关键测试场景,用户和目标并将其合并到模型中。最后,添加有界上下文之间的关系以创建上下文映射。然后用代码对所得模型进行挑战,以验证组学习并验证模型。
它通常由三个步骤组成:
模型探讨旋涡(whirlpool)是由 DDD 的创造者 Eric Evans 创建的一个模型探讨漩涡的文档草案(http://domainlanguage.com/ddd/whirlpool/ )。这份文档提出了一种建模和知识提炼的方法,它能补充其它的敏捷方法,并能在应用的开发生命周期中随时使用。不过,它主要不是用来建模的,而是为了解决在创建模型期间遇到的问题。
aka Groovy
Go 示例:
all: clean build
build: build-linux build-windows build-macos
test:
# make build-plugins
$(GOTEST) -v ./...
clean:
$(GOCLEAN)
rm -rf $(BINARY_DIR)
run:
$(GOBUILD) -o $(BINARY_DIR) -v ./...
./$(BINARY_DIR)
lint:
golint ./pkg/...
changelog:
conventional-changelog -p angular -i CHANGELOG.md -s -r 0
通过 package.json
中的 script
字段,如 Ledge 中的:
{
"scripts": {
"ng": "./node_modules/.bin/ng",
"start": "yarn ng serve",
"build": "node --max_old_space_size=4096 ./node_modules/.bin/ng build",
"build:ci": "node --max_old_space_size=4096 ./node_modules/.bin/ng build --configuration ci",
"build:stats": "node --max_old_space_size=4096 ./node_modules/.bin/ng build --stats-json",
"analyze": "webpack-bundle-analyzer dist/ledge/stats-es2015.json",
"test": "yarn ng test",
"test:ci": "yarn ng test --watch=false --progress=false --browsers=ChromeHeadlessCI --codeCoverage",
"lint": "yarn ng lint",
"commit": "git-cz",
"package": "yarn build:ci && rm -rf dist/static && yarn scully",
"deploy": "yarn package && npx angular-cli-ghpages --repo=https://github.com/phodal/do.git --dir=dist/static --cname=devops.phodal.com",
"publish:cloudbase": "cloudbase hosting:deploy dist/static -e ledge2-8daa6a",
"build:render": "node --max_old_space_size=4096 ./node_modules/.bin/ng build @ledge-framework/render --prod",
"build:view": "node --max_old_space_size=4096 ./node_modules/.bin/ng build @ledge-framework/view --prod",
"publish:render": "cd @ledge-framework/render && npm publish --access=public",
"publish:view": "cd @ledge-framework/view && npm publish --access=public",
"scully": "scully --scanRoutes",
"scully:serve": "scully serve",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0"
}
}
见:Pipeline
示例:
pipeline {
agent any
options {
skipStagesAfterUnstable()
}
stages {
stage('Build') {
steps {
sh 'make'
}
}
stage('Test'){
steps {
sh 'make check'
junit 'reports/**/*.xml'
}
}
stage('Deploy') {
steps {
sh 'make publish'
}
}
}
}
见:GoCD
工具特性:
迁移脚本
执行数据库变更,这些脚本是标准的 SQL 文件ArchUnit: ArchUnit 是用来检查架构特征的 Java 测试库,比如包与类的依赖关系、注解、甚至是调用层级一致性。它可以附加在现有的测试方案中,以单元测试的方式运行,但目前只能用于 Java 架构。ArchUnit 测试套件可以合并到持续集成环境及部署流水线中,使我们可以更容易地利用架构适应度函数实现演进式架构。
参见:《ArchUnit》
JDepend 设计质量指标:
官方指南:《Build effective unit tests》
分类 | 框架 | 覆盖范围 | 是否依赖设备 | 执行速度 |
---|---|---|---|---|
大型测试 | Appium, UIAutomator* | 用户通过界面操作的流程(涉及多应用和系统 UI 交互) | 是 | 慢,分钟级(一般在 1 ~ 5 分钟内,依测试场景复杂度而定) |
中型测试 | JUnit,Instrumentation | 功能测试:用户通过界面操作的流程(只能在单个应用内操作);集成测试:Java 方法(依赖 Android 框架、数据库、第三方能力实现) | 是 | 较慢,涉及界面操作的在分钟级(一般在 0.5~3 分钟,和同样操作步骤的界面测试相比,单个测试用例执行时间要少 40%);较快,不涉及界面操作的 Java 方法的测试在秒级(一般在 1 秒内,依被测方法的执行时间而定) |
小型测试 | JUnit,Mockito,Robolectric | “纯”Java 方法(不依赖 Android 框架、数据库、第三方能力,或这些依赖可以很方便的 Mock,对代码可测试性要求较高) | 否 | 快,毫秒级 |
类型:
相关资源:
Apache Benchmark:Ab
SuperBenchmarker(Windows 版的 Apache Benchmark): SuperBenchmarker
示例:
$ ab -n 10 -c 2 https://devops.phodal.com/
Gatling:Gatling
Eclipse MicroProfile 是一个微服务的基准平台定义,针对微服务架构优化企业 Java,并为跨多个 MicroProfile 运行环境提供应用程序可移植性。
Eclipse Microprofile Metrics:Eclipse Microprofile Metrics
MicroProfile OpenTracing:MicroProfile OpenTracing
TBC
Spring Boot Actuator:Spring Boot Actuator
监控,观察并记录系统状态变化和数据流的过程。
Ganglia是由UC Berkeley发起的一个开源监控项目,设计用于监控数以千几的节点。 每台服务器都运行一个收集和发送监控数据名为gmond的守护进程。 它将从操作系统和指定主机中收集。 接收所有监控数据的主机可以显示这些数据并且可以将这些数据的精简表单传递到层次结构中。
Nagios是电脑系统和网络监控程序,用于检测主机和服务,当异常发生和解除时能提醒用户;是基于GPLv2开发的开源软件,可免费获得及使用。 Nagios原名NetSaint,由Ethan Galstad开发并维护至今。
Cacti是一种基于Web的开源网络监视和绘图工具,设计为开源的,行业标准的数据记录工具RRDtool的前端应用程序。Cacti允许用户以预定的间隔轮询服务,并绘制结果数据的图形。它通常用于绘制CPU负载和网络带宽利用率等指标的时间序列数据。通常的用法是通过简单网络管理协议轮询网络交换机或路由器接口来监视网络流量。
Prometheus受启发于Google的Brogmon监控系统(相似的Kubernetes是从Google的Brog系统演变而来),从2012年开始由前Google工程师在Soundcloud以开源软件的形式进行研发,并且于2015年早期对外发布早期版本。2016年5月继Kubernetes之后成为第二个正式加入CNCF基金会的项目,同年6月正式发布1.0版本。2017年底发布了基于全新存储层的2.0版本,能更好地与容器平台、云平台配合。
Prometheus 生态圈中包含了多个组件,其中许多组件是可选的:
Kamon
记录工具:
SLF4J:SL4J
Apache Log4J 2:Log4J 2
OpenZipkin:https://zipkin.io/
Spring Cloud Sleuth:https://spring.io/projects/spring-cloud-sleuth
OpenCensus:OpenCensus
Prometheus 是用于事件监视和警报的免费软件应用程序。它将实时指标记录在使用 HTTP 拉模型构建的时间序列数据库中,并具有灵活的查询和实时警报。
示例架构:
ElasticSearch + Logstash + Kibana
Flink:Flink Downloads
Flink 中文:Flink 下载
Kafka:Kafka Quickstart
特性开关(Feature Toggle)是一种允许控制线上功能开启或者关闭的方式,通常会采取配置文件的方式来控制。当我们需要 A 功能的时候,我们就只需要把 A 功能的开关打开。当我们需要 B 功能,而不需要 A 功能的时候,我们就可以把相应的功能关掉。
——《DevOps 实施手册》
对应的挑战:
DevOps 是一项组织和文化运动,旨在加快软件交付速度,提高服务可靠性,并在软件利益相关方之间建立共享所有权。了解如何提高软件交付的速度、稳定性、可用性和安全性。
Google 示例:Google DevOps
原文:《构建可信软件系统》