当前位置: 首页 > 科技观察

如何将微服务架构与DevOps结合起来实现持续交付

时间:2023-03-22 01:45:15 科技观察

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