如何在细粒度的架构中更好的微服务。这里会从持续集成和持续交付提及。linux
1.持续集成简介安全
CI(Continuous Integration , 持续集成)服务器
CI可以保证新提交的代码与已有的代码进行集成,从而保证全部人保持同步。CI服务器会检测到网络
代码已提交并签出,而后花些时间来验证代码是否经过编译以及测试可否经过。架构
做为这个流程的一部分,咱们常常会生成一些构建物(artifact)以供后续验证使用。微服务
理想状况下,这些构建物应该只生成一次,而后在本次提交所对应的全部部署环节中使用。工具
CI的好处不少。经过它,咱们可以获得关于代码质量的某种程度的快速反馈。测试
CI能够自动化生成二进制文件。用于生成这些构建物的全部代码都在版本的控制之下,spa
因此若是须要的话,能够从新生成这个版本的构建物。经过CI咱们可以从已部署的构建物回溯到操作系统
相应的代码,有些CI工具,还可使这些代码和构建物上运行过的测试可视化。
持续集成容许咱们更快速,更容易的修改代码。
有人任务使用了CI工具就算采用了CI这个实践,事实上,只有工具是远远不够的。
测试别人是否真正理解CI的三个问题?
你应该保证代码可以与已有代码进行集成
若是没有测试,咱们只能知道集成后没有语法错误,但没法知道系统的行为是否已经被破坏。
没有对代码行为进行验证的CI不是真正的CI。
绿色的构建意味着,咱们的修改已经安全地和已有代码集成在了一块儿。红色的构建意味着,最后一次修改极可能有问题,
这时只能提交修复构建的代码。
2.把持续集成映射到微服务
前面已经提到过,每一个微服务应该可以独立于其余服务进行部署。
因此如何在微服务、CI构建及源代码三者之间,创建起合适的映射呢?
最简单的作法,以下
图 6-1 把全部微服务放在同一个代码库中,而且只有一个构建
这种方法从表面上看比其余方法要简单的多:由于你须要关心的代码库比较少,
并且从概念上来说,这种构建也比较简单。开发者的工做也获得了简化:
咱们只须要提交代码便可,若是须要同时在多个服务上工做的话,一个提交就能搞定。
在同步发布(lock - step release)中,你须要一次性部署多个服务。
通常来说,咱们绝对应该避免这个模式,可是在项目初期是个例外。
当仅有一个团队在全部的服务上工做时,这种模式在短期内是可接受的。
这种模式存在不少明显的缺点。
若是我仅修改了图6-1中用户服务中的一行代码,全部其余服务都须要进行验证和构建,
而事实上它们或许并不须要从新进行验证和构建,因此这里咱们花费了没必要要的时间。
更糟糕的是,我不知道那些构建物应该被从新部署,哪些不该该。
使用这种方式的组织,每每都会退回到同时部署全部代码的模式,而这也正是咱们很是不想看到的。
很不幸,若是这一行的修改致使构建失败,那么在构建获得修复以前,其余服务相关的代码也没法提交。
这种方法的一个变体是保留一个代码库,可是存在多个CI会分别映射到代码库的不一样部分。
如图 6-2
这种模式是个双刃剑。
一方面它会简化检出/检入的流程,可是另外一方面,它会让你以为同时提交对多个服务的修改
是一件简单的事情,从而作出将多个服务耦合在一块儿的修改。
可是相对于只有一个构建的多个服务来讲,这个方式已经好不少了。
还有一种比较好的方式,每一个微服务都有本身的CI,这样就能够将该微服务部署到生产环境以前作一个快速的验证。
如图6-3
这里的每一个微服务都有本身的代码库,分别于相应的CI绑定。
当对代码库进行修改时,能够只运行相关的构建以及其中的测试。
每一个微服务都有本身的代码库和构建流程。
咱们也会使用CI构建流程,全自动话的建立出用于部署的构建物。
3. 构建流水线和持续交付
把一个构建分红多个阶段是颇有价值的。
由于有的测试运行快,涉及范围小,有的测试运行耗时,涉及范围广,
若是放一块儿,快速若是失败,还会接着运行耗时的测试,这样就不合理。
解决这个问题的一个方案是,将构建分解成为多个阶段,从而获得咱们熟知的构建流水线。
在第一个阶段运行快速测试,在第二个阶段运行耗时测试。
构建流水线能够很好的跟踪软件构建进度:每完成一个阶段,就离终点更近一步。
流水线也可以可视化本次构建物的软件质量。构建物会在整个构建的第一个环节生成,
而后会被用在整个流水线中。
CD(Continuous Delivery, 持续交付)基于上述概念,并在此之上有所发展。
CD可以检查每次提交是否达到了部署生成环境的要求,并持续地把这些信息反馈给咱们,
它会把每次提交当成候选发布版原本对待。
为了更好的理解这些概念,咱们须要对从代码提交及部署到生产环境这个过程当中,所须要经历的流程进行建模,
并知道哪些版本的软件时可发布的。
UAT(User Acceptance Testing, 用户验收测试)流程。
经过对整个软件上线过程进行建模,软件质量的可视化获得了极大改善,这能够大大减小发布之间的间隔,
由于能够在一个集中的地方看到构建和发布流程,这也是能够引入改进的一个焦点。
在微服务的世界,咱们想要保证服务之间能够独立于彼此进行部署,因此每一个服务都有本身独立的CI.
不可避免的例外
全部好的规则都须要考虑例外。
当一个团队刚开始启动一个新项目时,尤为是什么都没有的状况下,你可能会花不少时间来识别出服务的边界。
因此在你识别出稳定的领域以前,能够把初始服务都放在一块儿。
在最开始的阶段,常常会发生跨服务边界的修改,因此时常会有些内容移入或者移出某个服务。
在这个阶段,把全部的服务都放在一个单独的构建中,能够减轻跨服务修改所带来的代价。
固然,在这个阶段你必须把全部服务打包发布,但这应该是一个过渡步骤。
4.平台特定的构建物
大多数技术栈都有相应的构建物类型,同时也有相关的工具来建立和安装这些构建物。
Ruby中有gem,Java中有JAR包和WAR包,Python中有egg。
可是,从微服务部署的角度来看,在有些技术栈中只有构建物自己是不够的。
因此为了部署和启动这些构建物,须要安装和配置一些其余软件,再启动这些构建物。
自动化能够对不一样构建物的底层部署机制进行屏蔽。
5.操做系统构建物
有一种方法能够避免多种技术栈下的构建物所带来的问题,那就是使用操做系统支持的构建物。
举个例子,对基于RedHat或者CentOS的系统来讲,可使用RPM;对于Ubuntu来讲,可使用deb包;
对于Windows来讲,可使用MSI。
使用OS特定构建物的好处是,在作部署时不须要考虑底层使用的是什么技术。只须要简单使用内置的工具就能够完成软件的安装。
OS包管理工具,能够帮你完成不少本来须要使用Chef或者Puppet来完成的工做。
其缺点是,刚开始编写构建脚本的过程可能会比较困难。
固然,还有另外一个缺点,即若是你须要部署到多个操做系统的话,维护不一样版本构建物的开销就会很大。
但若是软件时部署在你可控的机器上,那么建议,尽可能减小须要维护的操做系统的数量,最好只维护一种。
它能够大大减小不一样机器之间可能存在的不一样之处,并减少部署和维护的工做量。
特别是若是你在linux上工做,并且采用多种技术栈来部署微服务,那么这种方法就很合适。
6.定制化镜像
使用相似Puppet、Chef及Ansible这些自动化配置管理工具的一个问题是,须要花费大量时间在机器上运行这些脚本。
什么是蓝绿部署?
蓝绿部署容许咱们在老版本服务不下线的同时,去部署新版本的服务。能够减小在部署时,服务中止的时间增长。
一种减小启动时间的方法是建立一个虚拟机镜像,其中包含一些经常使用的依赖。
如今你能够把公共的工具安装在镜像上,而后在部署软件时,只须要根据该镜像建立一个实例,
以后在其上安装最新的服务版本便可。
你只须要构建一次镜像,而后根据这些镜像启动虚拟机,不须要再花费时间来安装相应的依赖,
由于它们已经在镜像中安装好了,这样就能够节省不少时间。若是你的核心依赖没有改变,
那么新版本的服务就能够继续使用相同的基础镜像。
这个方法也有些缺点。
首先,构建镜像会花费大量的时间。
其次,产生的镜像可能会很大。例如,当你建立VMWare镜像时,在网络上传送一个20GB的镜像文件会怎么样。
因为历史缘由,构建不一样平台上的镜像所需的工具是不同的。
6.1 将镜像做为构建物
我们能够把服务自己也包含在镜像中,这样就把镜像变成了构建物。
就像使用OS特定软件包那样,能够认为这些VM镜像时对不一样技术栈的一层抽象。
咱们不须要关心运行在镜像中的服务,所使用的语言是Ruby仍是Java,最终构建物是gem仍是JAR包,
咱们惟一须要关心的就是它可否工做。
这个简洁的方法有助于咱们实现另外一个部署概念:不可变服务器。
6.2 不可变服务器
经过把配置都存到版本控制中,咱们能够自动化重建服务,甚至重建整个环境。
可是若是部署完成后,有人登录到机器上修改了一些东西呢?
这就会致使机器上的实际配置和源代码管理中的配置再也不一致,这个问题叫作配置漂移。
为了不这个问题,能够禁止对任何运行的服务器作手动修改。
相反,不管修改多么小,都须要通过构建流水线来建立新的机器。
7.环境