微服务架构如何和持续交付过程相结合,是我们在实施微服务架构的时候必须要考虑的问题,如果是一个简单的单体应用的自动化编译构建和发布,相对来说要简单的多,但是在实施微服务架构后,整个持续交付过程本身会增加一定的复杂度。
我们举一个供应链系统开发的场景来说明,该供应链系统划分为了门户应用,招投标中心,采购中心,供应商中心,用户中心和流程中心几个大的微服务模块。基于微服务架构本身进行模块拆分的要求可以看到,以上的六个微服务模块要做到完全的独立自治,独立的配置管理库,并能够独立进行编译构建打包测试和最终的版本发布操作,而最终的六个微服务模块一起组成一个完整的供应链管理业务应用。
这个和多年前我们谈到的私有云PaaS平台里面的组件化开发思路是完全一样的。基于这种微服务模块划分,我们来看如何和持续交付过程和DevOps支撑平台相结合。
每个微服务模块独立进行配置和源代码管理,独立数据库,独立进行编译构建和部署发布。
在这种思路下可以看到,我们首先要有应用集的概念,即本次构建的供应链管理就是一个大的应用集,但是这个应用集下面却可以有多个微服务模块。整个思路是要先构建一个独立的应用集,并规划应用集的版本。然后才是在应用集下面创建6个独立的研发项目版本,分别对应上面的6个微服务模块,并制定独立的svn或git源代码目录分支。
针对每一个微服务模块都要独立创建编译,构建,发布等任务,同时针对每一个微服务模块创建一个独立的从编译构建测试到发布的流水线任务作业。 该流水线每触发执行一次,即可以完成该独立的微服务模块的自动化编译构建打包,自动化的代码检查测试并发布到测试环境进一步供测试人员进行测试。
每一个微服务模块只部署到一个Docker容器里面,不再进一步进行组件拆分部署到多个Docker容器中。但是容器本身可以在后期进行资源动态扩展。即微服微模块编译构建通过,打包制作镜像到一个镜像文件,并在后续对镜像文件进行部署。
问题:在实际的DevOps支撑里面,可以考虑将打包和镜像制作过程隐含点,毕竟用户并不关心该过程。
对于6个微服务模块间有接口调用,在前面我们思路里面是内部6个模块间的交互不用启用API网关进行交互,而直接走微服务架构里面的服务注册和配置中心即可。
在多模块交互协同下,所有的微服务模块在触发自动编译构建并部署后都需要自动化单元测试, 这里面最重要的就是对接口的单元测试,这种单元测试包括南向接口和北向接口两个部分的内容,只有两部分单元测试都通过,该模块本身才处于一种稳定可测状态。
自动化单元测试不通过应该先开发进行检查并解决,因此在多模块分工下更加应该首先对规划好的接口进行实现并发布,只有这样才不会影响到其它模块的并行开发工作。
最近我一直在思考,如果将整个持续交付过程规划为研发过程管理工具和DevOps支撑平台工具两个工具平台来支撑的话,实际上很多内容很难在两个平台间协同好。 DevOps平台更多是技术平台,仅仅解决的是构建和发布过程,而实际上很难去解决我们说的多个组件间的协同和研发过程管理。
开发人员和测试人员, 一种思路是测试人员手工执行流水线,在执行完成后进行测试操作;还有一种思路是开发人员去跑流水线,在自测没有问题后提交测试。 可以看到更好的做法应该是开发去跑流水线,提交测试后选择已经完成的需求或修复的Bug,自动变更状态。而测试人员只需要在测试环境对待验证的问题进行测试和验证就可以了。即只有问题状态是待验证,那么当前的测试环境版本一定就是可以验证的一个版本。
开发人员的流水线为:
代码更新-》编译构建-》代码检查-》镜像打包-》部署-》自动化单元测试-》人工验证并提交测试
在人工验证后提交测试,同时对相关需求和Bug的状态进行变更。测试人员可以进入到测试环节。实际上我们大部分重复迭代都应该在这个阶段,直到所有的需求全部实现,所有的Bug缺陷都关闭。
而基于上篇文章思考,在该流水线上可以再增加一个测试验证环节,即测试验证通过后自动进行环境迁移,将最新的版本发布到UAT环境以方便进行UAT测试操作。
如果考虑到流水线松耦合,那么可以将测试验证后发布UAT环境做为一个独立的流水线,即:
选择镜像(可以选择多个镜像)-》配置修改-》发布生产环境
在这个过程中镜像从镜像库选择,对应到当前项目的最新基线版本(基线版本为测试通过版本),即在开发流水线上仍然需要增加了一个打基线标签的人工操作,这个可以由测试人员来完成。
开发构建,发布和SIT测试是单微服务模块视角。但是整体的应用版本规划,UAT测试则是全应用集视角。即不论是新增还是后续变更版本的规划,我们都希望能够看到整个应用集的视角,包括这次变更究竟影响到哪些微服务模块,哪些会重新构建或发生版本变化,这些都必须清楚。
如果一个功能变更导致我们所有的微服务模块都必须重新编译构建和发布,那么我们进行微服务模块拆分,按微服务方式独立自治管理的目的就根本没有达到。 一个简单的原则就是影响到哪个模块就哪个模块进行更新,如果影响到接口,就接口对应的模块也配套更新。可见微服务模块间的接口一定得松耦合,如果拆分为微服务模块,但是之间的接口交互异常复杂,那么仍然是强耦合关系,没有意义。
唯一需要说明的是一种变更是变动了底层基础组件的接口规格,那么这种情况下往往才会出现大量的微服务模块都出现重新编译构建。基础组件变更,如果接口没有变更,那么上层的应用组件同样不应该重新构建,即相互之间应该是基于服务接口的依赖,而不能是基于Jar包的依赖。Jar包依赖容易导致的问题就是在使用Maven的时候会触发自动的重新编译构建操作。
从部署到DEV环境,再到部署到SIT环境,再到部署到UAT环境,整个过程必须进行全程跟踪。 形成基于当前项目版本的可视化追踪视图。这个功能实际在持续集成的时候也是必备的关键功能。
原文 http://blog.sina.com.cn/s/blog_493a84550102z2m9.html