传统软件项目交付中,各个角色分工明确,也暴露了不少软件交付中的不少问题。 DevOps的工做方式恰如其分的解决了其中一些问题,那么如何从传统交付流程迁移到具备伸缩性,灵活性,以及快速响应的持续交付中来,这种新的交付部署方式会给团队带来哪些变革,以及如何在大规模团队中落地。大规模团队将如何标准化的进行持续交付,以及它带来的便利和下一阶段的挑战是什么?前端
本文的五个部分:程序员
传统流程交付模式;编程
持续集成的交付模式;后端
微服务下的持续集成交付模式;缓存
标准化的演进案例;安全
下一阶段的挑战。服务器
首先,有这样一个案例:客户的IT部门刚刚成立,公司将这个部门交给了一个很是资深的产品经理(他原来是业务经理)。他负责整个IT部门的IT化构建,手下有一批业务人员,同时也是未来会是这批软件的使用者。他在收集一些反馈信息后给出了一些大型的需求列表,而后交给了咱们研发团队。架构
咱们研发团队和设计师沟通了一下,获得了一个设计版的结果进行了封闭式的开发,大概持续了6个月。产品作出来而后,研发团队将它交给了测试团队,并进行了大量的测试和全部的分支覆盖。通过几回测试不经过打回修改后,最后的结果是成功上线。框架
上述就是一个传统瀑布式的开发。有不少的公司曾经经历过相似的开发模式。这种传统瀑布式开发有如下的特色:less
第一,交付周期很是长,从产品的需求和最后的部署大概经历一年的时间;
第二,这整个过程当中没有任何的交付,交互也很少,也就是产品的需求到最后的开发的整个过程当中只有衔接部分有必定的交流,并无太多需求上的修改、调整和反馈。
这种交付方式就是无持续集成的交付模式,有如下特色:
第一,它的代码集成会很困难,由于全部人都在同一个仓库上工做,那么它天天就会有不少的代码提交和冲突。
第二,测试难,依赖性高。当咱们的软件部署到测试环节的时候,测试会将全部的需求进行一一测试,也就是测试会经历漫长的时间和全部的需求进行对比,这对测试的压力和测试难度也是很是高的。
最后,手动进行发布,发布对某些人的依赖性极高,并且风险大,易出错,也就只有1、两次成功发,这个软件就算是完成了交付的一部分,达到了可用的状态。
随着如今敏捷宣言还有持续集成(持续集成是由2014年提出的概念)的提出,咱们在开发过程当中进行大量的,而且天天都要进行集成,这样咱们能减小上线前集成所面临的压力。
上图是Jef所写的关于持续交付的书,它采用方法和理论是以迭代的方式将软件交到用户手上。那么,再加上硬件条件的提高,让持续集成在云计算的发展下将变得触手可及,即:虚拟环境容易获取。这样具有了硬件和软件条件,因此大部分人就开始享用持续集成的交付模式。
持续集成的交付模式的特色:
第一,交付周期短。持续集成通常是迭代的方式交付,咱们通常两周会有一个版本从端到端的构建、测试到发布。而且,沟通很是频繁,它的构建测试和沟通发布流程中都会有不一样的交互,好比说需求和开发人员的沟通,测试和需求人员一块儿讨论咱们的测试文档和测试策略。
第二,测试完备。咱们开发过程当中会有测试金字塔的概念,它的底部是大量的单元测试,开发会把全部的功能进行单元测试,金字塔的中间层是集成测试,顶端是端到端测试或者是系统大集成测试。因为手工测试成本很是高,有了大量自动化测试覆盖后,,它的数量也会比较少。
然而,测试的回归,也就是每次构建一个软件时,咱们怎样保证原有的功能是正常工做的,那就有大量的回归测试。而在持续集成的环境中,由于有大量的自动化进行覆盖,因此咱们回归测试的次数就会大大下降。
最后,自动化程度高。因为咱们进行每两周都会有一墙之隔迭代,就会有一个部署,那么这些当中咱们哪些东西是要重复作重复作,咱们怎样避免这样重复的事情?咱们就要自动化这些事情,采用自动化构建、自动化测和自动化部署一套脚本步骤作下来,这样能够避免大量重复的工做,同时也加强对项目部署时的信心。
下来咱们来对比一下持续集成和瀑布式这二种开发模式,能够看到持续集成是以4小步快跑的方式来进行迭代式交付,瀑布式是以时间为轴的线性交付。
另外,持续集成和瀑布式相比还有些不一样之处。第一,快速发布。持续集成发布更加快速,并且它可以及时获得用户的反馈,也就是我部署之后用户可以提出一些反馈交给业务人员,业务人员跟开发沟通后,进行下一个版本的迭代,调整优先集,调整咱们的需求。而后,它的速度更加频繁,也保证软件的质量更高。
第二,由于在整个的测试过程当中,包括自动化测试和人工测试。测试介入也是比传统的测试介入提早好久,因此它能保持测试的稳定性。
第三,对于进度把控来说,持续集成模式,因为咱们可以持续地看到咱们所产生的产品是什么样的,这样它对项目的管控可能更有直观的感觉。
最后,团队协做的提升。由于在持续以前的环境中,不一样的角色沟通更加频繁,因此持续集成的团队协做相对于瀑布式的任务交接的方式会有更好地提升。
首先讲一下微服务,微服务为何诞生?为何会有这样的架构演进?
微服务是相对于单体架构和面向服务的架构,也就是传统的单体架构。一个服务器接受全部的请求和处理,那么它就会面临一些问题。第一业务复杂的时候代码量变得很是大,咱们可能经过一些模块的方式进行划分,可是仍是难以具体去分功能的模块。
第二就是若是面临大量的访问请求的话,传统单体架构会面临一些瓶颈,复杂的业务和数据查询会使系统卡死。面临这样的问题,咱们须要进行缓存处理或者下降业务复杂度。微服务的出现,恰如其分的解决了这样的问题
下面我来说讲微服务架构的一些特色。微服务有5个特色:
领域建模;
去中心化;
服务隔离;
独立部署;
高度可监控。
对于单体架构而言,业务分离通常是采用模块划分的方式,好比把xxx,把用户做为一个模块,订单做为一个模块,支付做为一个模块。而对于微服务咱们能够将不一样的模块作得更极致,能够将它成为一个单体的运行服务,能够经过协议的方式进行沟通。
这种服务的分割方式能够采用DSL,不一样服务的性能要求和不一样服务的需求要求,咱们会采用不一样的领域语言。而后咱们这种拆分更加贴近业务原型,好比说支付模块面临支付有漏洞安全性的问题,咱们怎样解决,以后回滚,失败时怎样处理,对于这种领域性的问题,会创建更加贴切的模型。
再来说讲去中心化。原来单体架构一个中心,它须要处理全部的请求,一个错误或者异常可能致使整个软件崩溃。对于微服务而言,每个服务高度自治,这样的结构使得软件更加健壮,由于一个服务包宕掉不影响其余的工做,这样的服务架构可以表明组织结构。
由于目前而言,每5我的能够管理4—5个服务,因此我们公司一百个服务,那就有十几个Team,每一个Team都是扁平的结构,这种团队的架构就跟微服务是同样的。
接下来谈谈服务隔离。由于每个服务都有独立的服务器,因此服务经过契约沟通,咱们是经过Swagger来描述API的规范和参数返回值,给其余服务消费。另外就开发隔离而言,不一样的服务采用不一样的编程语言。
每个服务都分离开发,失败也能隔离,当一个服务宕掉其余的可以正常工做。
独立部署就是咱们能够想要选择本身须要的版本部署,也能够选择何时部署。因此微服务的部署是独立的,能够自主的灵活的部署,并且不一样的部署不会相互干扰。咱们在部署一个支付模块时,不用部署从主页获取信息的服务,因此主页部署也是隔离的。
最后说一下高度可监控。高度可监控与原来的监控性能状况不一样。
对于微服务来说,咱们要对每个服务进行性能监控,这样带来的好处是能准确地进行监控服务的运行时间的消耗。
这是咱们本身公司的一个页面,这是监控其余微服务的健康情况,来查看不一样服务是否可以正常工做。并且你能独立地监控每个服务的性能消耗,这时咱们就能更加有效地进行扩展,由于咱们知道哪些服务是瓶颈,哪些服务的性能CPU瓶颈高,咱们就会根据实时数据进行服务扩展。
接下来咱们分享一下澳洲的IT公司,为何会有这样的标准化,统一化的持续交付模式。当咱们谈论标准化时,咱们谈论的是怎样将它规模化,因此当咱们把服务从10个上升到100个,咱们怎样解决这些重复,这里面可能存在的一些问题。
我来介绍一下咱们公司的业务场景,可能接下来说实践时更有一些感觉。咱们公司是一家澳洲最大的博彩公司,当欧洲和澳洲有这些体育赛事时就会有大量的访问,尤为是比赛前半个小时,一分钟的访问量高达十几万的下注率,性能要求很是高。
咱们以前开发了一个软件是单体架构,花了两年的时间,最后投放到市场上,当这种大型比赛出现时,好比世界杯、欧冠,性能瓶颈和服务器响应能力很是慢,不能知足市场需求,致使了其余的竞争对手,原本咱们是澳洲最大线下门店巨头,如今线上咱们并未作的第一。
由于那个时候咱们用了单体架构的软件,并无有效地占领市场,用户的体验很是差致使用户选择了其余的品牌进行下注。公司痛定思痛,决定花重金从新开发一套全新的IT系统,也就是我要给你们介绍的微服务下持续交付的软件。每当这种大型的体育赛事,它的处理响应能力还有Devops对于监控咱们的性能问题,是彻底没有任何性能瓶颈,也就是如今是比较成功的案例。
接下来我要给你们讲一下持续交付流水线的构建图。上图中每个小方块就是一个服务,每一个服务都有不一样的部署阶段,好比UAT是给开发集成代码的部署版本。
而后,还有一个给测试用的集成平台,就是自动化地triger一下,就能够把代码分离部署到下一个环境,最后一个是产品环境的产品的部署。因此这些都是自动化的,每个服务都是独立部署。
标准化的持续集成的建设包含:
先后端分离架构;
Docker做为容器来提供微服务;
Api gateway;
AWS ECS;
服务发现;
日志;
监控;
Lambda。
首先讲的是先后端分离架构。由于咱们的业务需求是要有网站、PC端、手机端和Pad端;换句话说全方位让你们接触到业务。同时这也比较尴尬,由于在大多数国家是不容许这项业务存在的;可是在澳洲、欧洲博彩是税收的大头。
因此咱们要将先后端分离开来。先后的框架使用的语言都不一致,也是分离让合适的人作更合适的事情。先后端经过契约(Swagger)描述本身的接口,经过Rest API进行沟通来沟通。这种分离方式能够下降服务器压力。
咱们前端部署在两个Nginx服务器上。访问Server前端的页面,也就是每一个人只是访问了静态服务器页面。这个页面加载时会发不少的请求来获取数据。
在这个静态服务器被访问以前,咱们会有 load-balance 来决定哪一个服务器Server里的静态页面被访问。在这以前,咱们有CDN来给前端页面作缓存。也就是说一个区域的人访问前端页面,是由缓存提供给的。因此,前端服务器的压力会减小,而且大部分都是缓存起来了。
可是,缓存的前端并未减小后端服务器的压力。举个例子,好比说10万人要访问赛事信息,这是很是大的性能要求。10万人同时访问赛事信息和赔率时,10万人是平均数字,到了峰值最高,那么怎样解决呢?下面的小节来揭晓。
对于上述的问题,咱们首先采用Docker的部署和开发方式。Docker的好处是水平扩展性好,全部的容器都是能够随机调整个数和数量。
第二,它的服务是隔离的。关于Docker开发,我刚才提到了它和微服务的架构是互相不干扰,服务的健康情况不会影响到其余的服务。在构建服务的时候,咱们须要重复构建100多个服务。从0到1须要花不少的时间,从1到100先须要想到怎样构建通用的模板,由于每个服务咱们都要构建。
首先,咱们构建Docker Image;而后打包怎样作单元测试;最后上传到Docker HUB中去。这些工具都成一个模板,只要把这些模板应用到Docker,Docker会自动打包上传到DockerHUB里面去。咱们采用的一个SaaS的平台工具(Buildkite)帮助来作这个事情。
Docker也会涉及不一样服务之间的通信。由于某一个服务的变化可能影响到其余的服务,因此大家在交付过程当中可能有一些规范不同,这就须要的数据不同。咱们经过Swagger定义这些规范。
当一个服务的Swagger发生变化,它的信息发生变化,就会通知其余的服务,看那些服务会受到契约变化的影响。若是一致,就经过。若是不一致,就会及时告诉你两个服务之间有变化,并要求你必须解决。
服务之间能够经过Stub进行测试。可是,有这么多的依赖我怎样进行集成测试?这个须要用户的信息。但是这些模块没有信息,就要经过Stub进行交互。
最后,不一样服务能够采用不一样语言实现。其中最重要的一个模块就是下注的模块;就是说怎样把一个订单最后支付而后让它成功地下单。
以前,咱们用JS。它是一个单线程的动态语言,性能不是特别好(Node是单线程)。而后,咱们也是参考了Uber,采用大量的微服务架构,而且它有不少不一样服务转型的案例。接下来,咱们采用了Google出来的一款语言,它有大量的指针概念,你不用建立不少的对象,以下降内存消耗的方式来提升语言的性能。
因此,咱们微服务90%的是用JS,有些消耗更大的采用性能更高的语言。另外,咱们还采用Lambda,这不是一种语言是一种架构方式,和其余服务并列在一块儿使用。
当前端有大量的请求访问到服务器端时,因为咱们服务器端的性能不是很好,那么服务器端怎样处理压力?以及,怎样作这些请求?
API Gateway是解决这一方法的重要手段。当有大量的请求时,它会把请求导到咱们信息服务中去。可是,访问服务以前会有一个缓存,即访问同一个赛事信息,就直接把这个缓存给到前端。那么这些信息没有直接进行查询,而是缓存返回给了前端。因此,缓存是用来解决大部分静态信息获取压力的方法。
再则就是作统一的认证。在不一样的服务间,80%的服务是须要登陆信息,就是说登陆之后才能操做。怎样解决不一样信息之间的登陆问题?难道须要每一个服务在访问时必须访问登录认证服务?解决方式就是你的访问不是访问服务,而是网关。由于它储存了用户信息,也有token过时时间。
API Gateway全部请求访问网关时,咱们就能够记录下全部的访问信息和全部的日志。在不一样的服务之间的接口是不规范而且不一致,API能够帮助咱们作请求格式的转换。
上面咱们提到有一些服务须要进行大量的扩容。这个扩容过程当中咱们怎样肯定新起服务的端口?咱们采用的是Consol的服务发现的工具。
这个服务工具的大概工做原理是:每个ECS hosts 上都有一个Consol的service。由于全部的Docker都部署在ECS上,ECS上不只部署一个服务,还能够同时扩容3个、5个、8个。可是,这些服务都是随机端口,你不知道地址在哪里。
这个时候,每个ECS上都有一个 Consul 的实例。这个 Consul 实例会将ECS上全部的服务的地址、IP和端口记录下来上传到中央控制服务发现区。而后,API Gateway直接访问Console Master来知道哪一个服务布置在哪一个端口上、哪一个IP上。这样就解决扩容的时候,服务器在随机端口的应用状况。
监控日志对于产品性能是很是重要的。对于传统单体结构,多是全部的CPU都在对应的服务器上,一旦扩容全部的都扩容了。可是,咱们想精确地知道这些服务的瓶颈,并实现定向地扩容来有效地解决瓶颈问题。对于日志而言,它知道咱们产品的问题,能够进行准确地定位。
因此,日志是直接的手段也是常常用的手段。于是对不一样的服务咱们会采用统一规范的日志,好比说记录用户的IP,记录用户访问的时间,记录请求的数据以及记录一些错误。
Lambda的特性是:
计算服务
无服务器
自动扩展
日志和监控
因为咱们有的服务不须要任何存储,只须要计算资源。好比说一个生成随机数,咱们须要给用户赔率随机翻倍的功能。这样的话,你能够天天有一个权利来得一个随机翻倍的次数。这个服务只须要产生一个随机数给下注的服务使用,因此随机数不必单独开一个ECS来单独服务这个服务。
Lambda就是无服务器的功能。而后,它能够自动扩容。上图是Lambda的状况,蓝色的是次数,红色的是规模,因此是很是吻合的。它对于business是很是适合的,并且这种场景是很好的。
具体某个服务的架构图
这是咱们的一个小的微服务的架构:用户访问一下Gateway,而后访问你的服务,服务和性能记录到不一样的云平台上,Ops就能够监控如今的云平台的状况。
最后,讲一下面临的挑战,主要是人的挑战,还有一些技术的挑战。
人的挑战是咱们如何管理咱们的组织。由于大型的传统金融保险公司都是金字塔式的结构,就是经理、职员、小组。这种结构就会对传统的人员架构产生冲击。每个小组都是一个微服务,有一百个就是二十个、二十个小的团队。这些小的团队怎样组织在一块儿。不一样的服务之间都有不一样的小组,那这些小组之间的沟通怎样解决他们之间面临的问题的。这就产生了孤岛效应,你们不知道对方在作什么,也不知道对方面临的问题是什么。
因为不一样小组之间有本身的优先级,每个都认为本身作的优先级是最高的,这就面临资源竞争。咱们是否是要招最好的程序员,用最好的资源。
还有技术债,不一样团队面临的技术债不同,怎样解决一些别人已经解决过的问题。这就须要团队信任。虽然,不一样的团队之间进行交互的频率很是少,可是可能会存在信任问题,即:我怎样使用,你的API是否是不稳定,前端获取数据是否跟你不一致等问题。
总之,微服务只是为了解决问题的手段,不必把全部的事例都以微服务实现。只要解决本身的问题,它就是一个正确的方式。
http://mp.weixin.qq.com/s/4famcSoL-ObEBdfJ4Z0ckw