基于微服务的DevOps落地指南 交付效率提升40%
基于微服务的DevOps落地指南
交付效率提升40%
2015-2016年,珍爱线下门店已新增覆盖城市9个,与此同时,CRM系统大小故障却发生了数十起... ...
珍爱网是以“网络征选+人工红娘”模式提供婚配服务的婚恋相亲平台。CRM系统承载了整个珍爱网会员的全生命周期管理,涵盖资源挖掘、用户触达渠道以及服务跟进体系。
CRM系统对珍爱5400名红娘来说,是承载她们全部工作的核心平台;对公司业务来说,承载着引流、转化、支付、客户服务等全部环节。最最重要的是,公司收入的80%都是依托CRM系统完成的。
然而在珍爱网成立10年之际,运行10年之久的CRM系统已不足以支撑业务的快速发展了。
我们为什么要做DevOps
经过分析,我们发现CRM系统目前面临着以下问题:
技术上——
传统的系统架构,不再适应敏捷开发,模块耦合,数据库存在单点故障;
容错性差,冗余代码多,修复bug和实现新功能变得困难和耗时。
产品上——
产品功能不够场景化、电子化、智能化;
无法快速响应业务变化,迭代周期长。
我们可是背负着“成就天下姻缘”使命呢,系统重构,研发流程改进,迫在眉睫。
2017年1月25日,捷豹项目组成立,只为给业务打造一个“简单·好用”专注于婚恋相亲的综合服务平台。
捷豹CRM系统(PC端、Pad端、小程序端)的版本发布周期为一周一个常规迭代,紧急版本按天发布。
捷豹CRM系统整体设计思路如下图,我们希望能够实现系统的服务解耦、动静分离以及高可用。
然而大家都知道,微服务架构中每个服务都具有业务属性,并且能独立地被开发、测试、构建、部署。换句话说,每个服务都是一个可交付的“系统”。
那么问题来了,如何让需求以小批量形式在团队的各个角色间顺畅流动,并以较短的周期完成小粒度的持续发布呢?
答案当然是 TAPD DevOps流水线,简直是神助攻!
整体效果
TAPD DevOps流水线支持集成主流的研发工具,覆盖产品研发全生命周期,提供可视化交付流水线,可以将DevOps各个环节进行统一展示和管理,真正实现一站式持续交付。
自2017年10月起,我们就应用TAPD的DevOps流水线,开展了一系列持续交付和持续改进实践。
CI和CD实现过程使用Gitlab、Jenkins、Sonar、Jacoco、Nexus、EasyOps、Docker、Kubernetes等工具,分别在代码管理、集成编译、包管理、自动化测试、发布阶段集成到TAPD流水线统一展示和管理。
在TAPD流水线实践DevOps的过程中,我们也打通了各环节的研发数据。
通过TAPD迭代详情中的Dashboard,可以统计并展示当前迭代的研发效能数据,包括:需求完成情况、缺陷新增和解决情况、代码提交与关联趋势、每日构建统计、构建产物版本情况、自动化测试、部署发布等全过程数据,研发效能度量更直观、更深入,让改进方向更明确,也让效能提升更明显。
基于以上持续交付和持续改进实践,我们的研发效能也有了质的提升。
我们从业务响应周期、持续交付能力、开发质量、交付质量四个方面来衡量研发效能,下图展示了各个维度的改进效果。
我们的DevOps是如何落地的
那么我们具体怎样利用TAPD DevOps流水线,一步步实现持续交付,最终提升研发效能的呢?
下面我将分享我们在各个环节的做法。
1 代码管理环节
1.1 建立TAPD分支管理规范
改造前:
开发编码过程中最崩溃的应该是:“我刚写好的代码又被谁覆盖了!”
并行开发过程中,最痛苦的莫过于开发的需求太多, 记不清哪个需求在哪个分支上,或者多个需求在一个分支上开发,撤代码撤到望眼欲穿……
改造后:
通过走访调研,最终我们确定遵循“一个需求一个开发分支”的原则,方便管理且可追溯,并行开发,互不干扰。
在Jenkins上创建Job,通过TAPD和Git的API,将TAPD需求ID与Git分支关联,创建的分支名为“工程名-创建日期-TAPD需求ID”,开发小哥哥去Gitlab上拉创建好的需求分支便可努力搬砖了。
待需求上线后转关闭状态的21天,自动将该分支删除,整个分支管理过程实现自动化。
效果:
截至目前, 通过该Job创建分支次数达到1564次,创建成功的分支数远大于1564*3 个,而合并冲突数小于5次。
1.2 TAPD源码关联
改造前:
在测试过程中, 最繁杂的应该是代码合并环节了,一个需求涉及到多个工程的代码变更,每天各个开发针对不同的需求,提测到测试同学进行代码合并。
开发/测试的比例为4:1,需求涉及的前后端工程40余个,面对一个需求到底要合并哪些工程,测试同学每天要在风中凌乱好几回……
改造后:
与研发效能度量深度结合,良好编码习惯,从源码关联开始。
通过源码关联功能,我们实现了以下闭环:
所有研发任务都必须录入TAPD,并且只能通过需求ID来创建Git分支 → Commit信息必须关联源码提交 → 度量数据只获取关联源码的代码行 → 根据这部分数据进行研发效率和质量的度量。
由于提交比较频繁,我们写了一个爬虫脚本,将抓到的版本库去重,得到该需求要合并的工程。然后我们将待合并工程,生成TAPD的合并任务分发给指定同学,将整个过程自动化管理。
效果:
综上,通过“源码管理”和“TAPD分支规范”,有效规避了代码管理过程中,冲突多、管理乱、不可追溯的问题,同时也实现按需求粒度、灵活发布的效果。
自2018年10月以来,通过这套代码合并任务自动分发方案,我们成功迭代上线了18个常规版本和10个紧急版本,整个过程简单清晰,单任务合并整合环节,从原来的40分钟,减少到5分钟。
2 代码质量分析
改造前:
Sonar其实很早就开始在项目过程中使用了,但是效果并不太好。
无论对于开发还是测试同学,都需要多维护一个系统,并且改动频繁,当某一个服务经手的开发过多时,Sonar扫描出问题后无法快速分配责任开发。
另外Sonar配置到集成环境构建时触发,让bug从发现环节开始滞后,修复过程也对版本稳定性带来风险。
改造后:
在2018年底,我们发现TAPD流水线集成Sonar,还可以一键创建缺陷到TAPD。
于是,我们将Sonar扫描前置到开发每一次提交到Git仓库便触发构建,让Sonar缺陷在开发自测环节变暴露出来,同时,每一次构建能清晰的展示本次代码变更人,开发可以安心地收下这一页的bug啦。
当然,有的开发小哥哥可能没有及时修复,没关系, 测试小姐姐将未及时关闭的Sonar缺陷通过“批量导入缺陷功能”每天自动化(通过TAPD的API实现)创建到你的缺陷清单里,开发小哥哥再也不会错过那些被遗忘的bug啦。
噢,贴心的TAPD还在缺陷详情里把bug的文件名和代码行都给展示了呢,开发小哥哥和测试小姐姐终于可以不跨系统维护Sonar了。
需求分支经过静态扫描和自测通过后就要提交到集成环境啦。
在这个环节,除了常规编译步骤,我们还增加了开发的单元测试和Jacoco覆盖率检测。在集成环境我们也增加了Sonar进行最后一次扫描确认。
单元测试框架为JUnit,与TAPD进行关联,构建后在“自动化测试”板块可以看到本次构建的单元测试用例总数和通过率(单元测试通过率是我们对研发质量度量的一个很重要的指标),单元测试不通过的case和Sonar扫描的bug处理方式一致,由API脚本统一录入TAPD缺陷进行跟踪。
单元测试的覆盖率情况,方便开发同学分析单元测试用例对测试对象的分支覆盖情况。
编译后就是Sonar进行最后一道集成环境的全量代码扫描工作了。
我们在包管理环节的实践主要分为对 “jar包”和“Docker镜像”的管理。
构建生成的jar包,推送到Maven仓库(用于其他项目的依赖引用)。将Nexus集成到TAPD,通过“构建产物”可以看到软件包的详细信息。
同时,流水线可以清晰看到构建步骤的耗时分布,也帮助我们有针对性地去优化构建效率。
然后进行Docker镜像打包,推送到Docker仓库,生成配置,并推送到配置仓库。
顺便说说为什么要用Docker吧!
项目初期只有一个dev环境,随着版本构建的频繁,稳定的测试环境对测试同学来说尤为关键,但是部署一套40余工程的环境对运维同学来说工作量也非常之大,于是我们引入了容器技术。在环境搭建、应用迁移方面都有很好的收获。
同时,基于珍爱的业务背景,特别是对于特殊节日搞活动时候,容器化能快速对服务进行横向扩容;减少对环境的依赖,部署快、扩容快。同时容器运行时会对服务运行环境进行隔离,也有效提升了安全性和服务运行的稳定性。
自动化测试分为接口测试和UI自动化测试两个部分。
接口测试主要通过开源工具实现,但涉及到跨系统维护,以及测试结果不能很好地跟踪,因此在TAPD上尝试用Python Unit Test做些核心场景的接口测试,以便于将这部分测试纳入到整个研发流水线当中,构建成功后自动触发场景接口测试,失败的用例也能直接在TAPD跟踪。
UI自动化,则是我们自己研发的平台,通过关键字驱动实现,并增加了代码覆盖率检测,以帮助测试人员分析哪些分支情况是没覆盖到的。
测试结果转为XML格式后也可以统一集成到TAPD管理,可以清晰直观地展示自动化测试结果。
目前我们的自动化用例覆盖业务流程达239个,case成功率94%,运行时长15min,代码覆盖率21%。
我们整个发布流程简单分为以下几个步骤,部署发布环节主要用主流部署工具完成。
研发效能度量
每月通过TAPD产生的过程数据进行研发过程效率和质量分析。同时我们也设立了相关奖项激励大家正向PK,提升效率的同时更加重视研发质量。
研发效率分析
得益于TAPD的强大API,我们可以拿到需求交付过程数据。
通过深入分析,我们可以知道效率较低的环节到底是什么原因导致,以制定更有效的提升效率的方案,可以是流程自动化,也可以是制定规范。
研发质量分析
而研发质量分析方面,我们希望能在团队内部形成重视研发质量的共识和文化。
我们会统计出研发同学本月上线的任务数、代码行、花费、生产bug,来计算出有效花费,遵循“好、多、快”原则,评选出优秀的个人和团队进行表彰鼓励。
噢,TAPD的API好好用,以上提到的脚本均由测试同学通过API实现,你会发现高效的质量度量是一件特别有意思的事情,质量度量后的效能提升更是一件特别有成就感的事情!
总结
珍爱网捷豹CRM项目,应用TAPD DevOps可视化流水线,集成业界主流研发工具,实现一站式持续交付管理,让整个研发过程清晰、直观、透明。
在这一过程中,我们基于TAPD提供的API接口,进行了二次开发,实现了多个环节的自动化闭环。
此外,我们通过API以及TAPD Dashboard,获取持续交付过程数据,从而进行研发效率和质量的分析以及持续改进。
基于以上实践,我们从业务响应周期、持续交付能力、开发质量、交付质量4个方面衡量的研发效能,都有了显著的提升。
我们将持续在此基础之上不断完善和优化,挖掘TAPD DevOps流水线的更多场景,全方位提升研发效能。
基于微服务的DevOps落地指南 交付效率提升40%的更多相关文章
- 微服务与DevOps关系
随着IT技术的不断发展,从传统的IT建设模型逐步向新型IT建设模型过渡,建设模式的改变,必然影响应用系统的全生命周期.应用系统的建设经过单体应用.SOA应用.逐步走向微服务应用,至于何为单体应用.SO ...
- 微服务架构:基于微服务和Docker容器技术的PaaS云平台架构设计(微服务架构实施原理)
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 基于微服务架构和Docker容器技术的PaaS云平台建设目标是给我们的开发人员提供一套服务快速开发.部署.运维管理.持续开发持续集成的流程 ...
- Kubernetes才是微服务和DevOps的桥梁
一.从企业上云的三大架构看容器平台的三种视角 一切都从企业上云的三大架构开始. 如图所示,企业上的三大架构为IT架构,应用架构和数据架构,在不同的公司,不同的人,不同的角色,关注的重点不同. 对于大部 ...
- .NET Core/.NET5/.NET6 开源项目汇总6:框架与架构设计(DDD、云原生/微服务/容器/DevOps/CICD等)项目
系列目录 [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...
- eShopOnContainers 是一个基于微服务的.NET Core示例框架
找到一个好的示例框架很难,但不是不可能.大多数是小型Todo风格的应用程序,通常基于SimpleCRUD.值得庆幸的是,Microsoft已经为eShopOnContainers创建了一个基于微服务的 ...
- 基于微服务API级权限的技术架构
一般而言,企业内部一套成熟的权限系统,都是基于角色(Role)的 访问控制方法(RBAC – Role Based Access Control),即权限 (Permission)与角色相关联,用户( ...
- 基于微服务架构、运行于容器中的.NET Core示例应用eShopOnContainers
eShopOnContainers 是 <.NET Microservices – Architecture for Containerized .NET Applications>这本微 ...
- Asp.Net Core 轻松学-基于微服务的后台任务调度管理器
前言 在 Asp.Net Core 中,我们常常使用 System.Threading.Timer 这个定时器去做一些需要长期在后台运行的任务,但是这个定时器在某些场合却不太灵光,而且常常无法 ...
- 基于微服务的父maven依赖
<dependencies> <!-- spring-boot核心 --> <dependency> <groupId>org.springframew ...
随机推荐
- 解析JavaScrip之对象属性
对于面向对象编程语言(如java,.net,php,python等)来说,其最大的特点在于“面向对象”,而"面向对象"较为显著的特征便是:封装,继承,多态.借助”面向对象“的这些特 ...
- xddpay.com 个人支付接口接入流程
作为一个独立开发者产品需要支付接口是挺麻烦的,支付宝微信都不对个人开放,注册公司维护成本太高,市面上各种收款工具要么手续费太高,要么到账很慢,体验很不好. 看到 「小叮当支付」 这个收款工具,挺有意思 ...
- Linux下批量添加用户
添加和删除用户对每位Linux系统管理员都是轻而易举的事,比较棘手的是如果要添加几十个.上百个甚至上千个用户时,我们不太可能还使用useradd一个一个地添加, 必然要找一种简便的创建大量用户的方法. ...
- 【学习笔记】tensorflow图片读取
目录 图像基本概念 图像基本操作 图像基本操作API 图像读取API 狗图片读取 CIFAR-10二进制数据读取 TFRecords TFRecords存储 TFRecords读取方法 图像基本概念 ...
- Go开发之路 -- 函数详解
声明语法 func 函数名 (参数列表) [(返回值列表)] {} Golang函数特点 a. 不支持重载,一个包不能有两个名字一样的函数 b. 函数是一等公民,函数也是一种类型,一个函数可以赋值给变 ...
- HTML5跳转页面并传值以及localStorage的用法
1.首先,你得在那个页面把数据存入localStorage中吧.这个是必须的! localStorage.setItem("user",JSON.stringify(data.al ...
- PhpStorm 运行出现502 Bad Gateway
打开PhpStorm,菜单栏File --> Settings... 一.点开Languages & Frameworks 选PHP PHP language level:选PHP版本, ...
- 前端项目git操作命名规范和协作开发流程
前言 一个项目的分支,一般包括主干 master 和 开发分支 dev,以及若干临时分支 分支命名规范 分支: 命名: 说明: 主分支 master 主分支,所有提供给用户使用的正式版本,都在这个主分 ...
- 当view为wrap_conten时获取一个view的具体宽高
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec. ...
- QT 启动shell脚本
1.QProcess *p = new QProcess(this); 2.QString str = qApp->applicationDirPath() + "/update.sh ...