DevOps是最近非常火的一个概念,谈IT流程建设不说点DevOps都不好意思和人打招呼。但是DevOps究竟是个什么东西,这个东西能不能用?怎么用?什么样的情况才叫做DevOps落地成功?对于这些问题的答案,虽然网上有铺天盖地的文章和教程,但是一般来说都是从理论或者方法论上去阐述,也有大厂的实施经历。个人就感觉这里的它山之石,很难攻玉了。最终还是得思考下DevOps的由来,综合自己所在企业的现实状况去考虑。
在这篇文章中,本人无意对DevOps从理论或者方法论上做说明和讲解,只是想综合自己工作过程中的一些现实情况,在解决和优化一些现实情况的过程中,接触到了DevOps这样一个概念,想试着在DevOps这条路上找到一些解决问题的可行性和落地方式。本文是基于这个目的来做的一些总结,提到的概念和方法不一定和网上其他的教程/文章描述的一样,我只是想提出我的理解,希望各位看客轻拍,可以留言或者私信交流。
一. DevOps作为一种软件开发手段和方法
先引用下百度百科上对DevOps的描述:“DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。”我对这句话的理解,就是利用各种技术和管理手段来使整个软件工程更加的高效。为了更好的理解这样一个概念。就有必要去了解下在DevOps出现之前,有哪些软件工程流程,为什么在当前的情况下,需要有DevOps的出现,才能更好的理解这些技术或者管理手段的目的和意义。
软件行业的江湖中一直流传着这样类型的传说,某位大神闭关若干月,凭借自己无上的神功,在车库/地下室等各种不同简陋的地点开发出牛逼的一塌糊涂的产品。行内的各位肯定对这样的传说并不陌生。但是我个人认为其中有夸大的成分,不可否认,某位大神可以凭借自己无上神功搭出产品的核心框架,但是最终成熟的商业产品肯定是需要一个稳定的团队,依靠可靠的流程手段来维持和推进,缺乏有效管理的产品会变成一个焦油坑(人月神话)。
那么,这样一个可靠的流程手段就是我们通常讲到的软件工程:
a. 最初的阶段,我们的软件产品只有有限的需求,业务对软件的依赖也不是那么的大,因此有相对较长的交付周期。对于这样的一个应用场景,就有了最初的瀑布模型:
瀑布模型为了保证整个软件可控,从而保证软件产品质量,对每个阶段进行管控,只有前一个阶段的输出稳定和质量过关后,才能进入下一个阶段。
这种模型在需求量相对简单和少的情况下,可以做到可控。但是随着社会的发展,各行各业对软件的依赖越来越大,各种复杂的业务都需要有软件的介入,复杂的业务场景,更短的开发周期,更频繁的业务场景变更,导致瀑布模型的开发模式无法保证有效和高质量的产品开发。因此我们需要有更好更适合的开发模型。
b. 最简单的,我们采用分而治之的方法,将整个软件需求拆分成若干个子集,将整个过程拆分成若干个迭代,每个迭代挑选出若干子集采用瀑布模型的方式进行开发。称之为迭代模型。
这样,可以保证在每个迭代开发周期中,形成一个可交付的产品子集,逐步增量的进行交付。
理论上讲,通过控制迭代的需求范围,迭代开发可以适用大多数软件开发场景了。但是随着互联网和移动业务的崛起,对于软件的更新/构建速度提出了前所未有的要求。在迭代开发中,每个迭代还是走的需求设计/概要设计/详细设计/开发/测试/部署的流程。一旦一个迭代的范围和时间确定,为保证质量,原则上是不调整需求的。而一个迭代的流程下来,少说一个月两个月的。但是在移动互联网时代,为了快速响应用户需求来占领市场,需求是不断变化的,根本没有可能等待一个迭代结束之后再重新调整需求。因此,面向用户需求的软件开发理念就迅速在业界流行起来,也就是敏捷开发。
c. 我们来看一下敏捷开发的定义,引用百度百科上的定义:
敏捷软件开发(英语:Agile software development),又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的新型软件开发方法,是一种能应对快速变化需求的软件开发能力。它们的具体名称、理念、过程、术语都不尽相同,相对于“非敏捷”,更强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重软件开发过程中人的作用。
我个人对这个定义的理解是敏捷开发是一套方法论,为了适应频繁变化的需求而产生的。而在软件开发流程上相对于上述的瀑布和传统迭代模型而言,最关键的变化就是从面向书面的文档转变为面向人员合作。在上述的流程中,强调的是每个阶段的可靠性,只有当每个阶段的输出完成后才进入下一个阶段(包括文档输出,文档也会作为一个重要的输出,成为下一阶段的输入)。而敏捷开发更强调的是人与人之间的合作和沟通,而不是依赖文档(当然,不是不需要文档,必要的文档记录是很重要和必要的工作)。为了保持足够有效的人员沟通,团队的规模就不可能很大。因此就只能是小而精的团队,通过有效的沟通快速将需求实现。从而小步快跑的进行快速迭代。
上面是一个敏捷开发的一个方法论,不是一个具体的实现方法,一个比较著名的方法就是scrum。
而在快速迭代的过程中,每个需求和阶段的重点是通过人员之间的合作来推动,而人总是没有机器和工具的可靠(也就是说,人总是会犯错),为了保证质量和流程的稳定,一系列的工具被开发出来,这些工具也成为了敏捷开发的一部分。
因此,我理解的敏捷开发应该是一套实现了方法论的实践 + 工具集合。
讲到这里,就想先引入下所在企业的现状,碰到的问题及问题的思考,在这层思考的基础上去考虑DevOps的可行性和落地方法。也就是说,本人是想将DevOps作为解决方案之一来做思考的。
二. 企业软件开发流程现状
本人所在企业的业务是ToB的业务,和移动互联网从需求层面来讲是有很大区别的。一般来说,ToB的业务都是面向某一个特定的行业,行业属性极强,比如医疗,工业等领域,作为IT界的专业人士完全无法了解到其中的专业知识,更有甚者连最基本的常识都没有。这点和大多面向ToC的移动互联网不一样,移动互联网的业务一般都是基于常识,比如基于个人消费的电商,音乐软件等,产品经理都可以基于常识+个人体验做到对用户的引导来提出需求。这点在本人看来,对于开发流程是至关重要的,因为不管是什么样的流程,都是源自于需求,而软件本身只是一个人类生活中实现各种业务需求的工具,偏离了需求,软件也就没有存在的价值。
上面的一大段提到的问题会衍生出下面几个关键问题:
因此,在实际的软件开发过程中,企业的开发模式应该是处于半敏捷开发的模式。整体来说还是需求->设计->开发->测试的模式。在产品开发初期及产品成型后的交付初期,需求相对确定,产品规模和业务复杂度较低,团队规模也不大。
在半年到一年的交付之后,需求复杂度和代码耦合性越来越高。这个流程越来月陷入到焦油坑中:
可以看到,敏捷开发模式逐步退回到迭代模型中。由人员合作为导向变成了由文档为导向,每个阶段的“墙”越来越厚。
2. 堆积如山的环境
一般来说,刚开始我们是规划了几套环境来保证日常的开发工作
当项目越来越多时,每个项目都需要配置相同的环境。还有一些专用的环境,比如性能测试环境,为了保证稳定和演练上线步骤出现的预发布环境等等。光是环境都有一大把。虽然在现在虚拟化和容器技术的支撑下,不需要机房里堆上一大堆的物理服务器,但是对于每台虚拟机的管理也是一个相当繁琐的工作。也是影响交付效率下降的一个重要原因。
3. Dev VS Ops,难以调和的矛盾
我们的团队中没有专门负责部署和运维的团队,一般由开发或者测试的人来兼任这部分工作。但是不阻碍我们可以把这两部分工作区分开来考虑。对于已经商用的项目,规划多少需求到一个迭代中去开发和交付,是对整个团队的选择题。是尽可能多的上新的需求还是降低风险尽量少的控制需求是每次都会纠结的问题。
虽然没有两个团队之间的部门墙问题,同样还是存在Dev和Ops之间的矛盾。
4. 解决方案之一 -- DevOps
上面说了这么一些,总的说来就是研发和交付效率随着业务和代码的复杂度上升而显著下降,就需要有更好的流程和工具来解决这样的问题。自然而然的,团队就将注意力放到了大火的DevOps上。
是否要用DevOps,不是因为别人用了,我们就要用。首先想了解下DevOps是什么,能解决什么问题,和现在的方式方法有什么区别,然后才能对症下药。
在敏捷开发中,已经将整个软件开发流程中的 需求->开发->测试三个环节囊括在内,指导这三个阶段的相关团队提升效率。
从上述的图中看到,在整个软件生命周期中的最后一个环节:部署没有被囊括进去,也就是你前面玩的再High,对于部署团队而言,输出件都是不被信任的(指输出质量,不带我玩,为啥要信你,你说啥就是啥?)。而DevOps就是想把最后这个环节也囊括到这个大循环中。
最终的目的是想让在这个循环中的各个阶段团队都对整个产品和整个交付过程负责,而不是只对某个阶段负责。
回到文章的最开头,DevOps的定义里提到用的是一系列的工程方法和工具来提高效率。也就是说,用工具使得这个循环能顺利的转起来,并且要自动化的运转起来,在保证质量的前提下再越转越快。
三. DevOps的实践方式
上面提到了当前的几个问题:
那么就考虑下DevOps提供了哪些方法和工具来解决这些问题,从网上盗了一张图,是每个阶段的工具集合(侵删)
看完了简直是一脑壳包,所以要梳理下。
是否引入一个新的工具或者方法的时候,总要有一个判断标准,根据数字化的标准去判断是否由于当前的方法和工具。对于研发效率这个方向而言,有下面几个指标可以参考:
或者说,我们就是要从这想办法提高这几个指标。
或者从软件工程的角度理解,我们可以把往DevOps演进可以逐步分成下面几个阶段:
也就是说,我认为提高效率的过程中(不管是不是DevOps),都是可以针对性的去提高这几个指标,逐步的演进到下一个阶段。在这个过程中来针对性的选择工具。使用工具就是想让各个流程步骤自动化,避免对人的依赖。
1. 开发自动化,主要从配置管理,代码托管(Git),代码评审(GitHub),代码静态检查(sonar),单元测试(JUnit),配合Jenkins工具来提高。
2. 测试自动化,引入自动化测试
3. 运维自动化,引入环境监控(Portainer),日志收集等工具
具体的工具介绍就不写了,这个不是本篇文章的重点。策略就是发现瓶颈,解决瓶颈。发现人工部分,考虑工具来替代人工操作,不断循环往复的过程。
实际上,这里必须摆脱“器”或者“术”的思路,而要采用“道”的思路:
四. DevOps是一种态度和文化
绝大多数提到DevOps的文章都会提到,DevOps包含了两个部分,工具和文化。上面已经针对工具做了一个简单的思考总结。现在来谈谈文化。
企业文化就是一群人的做事风格,或者说是在做选择题,做决策的一种指导思想。而DevOps就是想提供一种有效的选择和指导思想。
最后,引用网络上的一句话,文化 = 人 + 流程 来做一个小小的总结。