Microservices 场景下的持续部署 | 吕健

内容简介

近两年作者在海外交付中参与 microservices 下的团队,为客户提升 Finance 系统的扩展性。作者所在团队,3 对开发(pair programming, 2 个 dev 为 pair)为客户支撑着 11 个 services,持续部署流水线(CD pipeline)是其中必不可少的一个技术实践。本次分享作者将从实践的角度分享 microservices 架构下的持续部署(CD)。内容概述

  1. 1. microservice 概述:简要介绍 microservice 架构下的挑战
  2. 2. 持续部署实践:这里会提到『Build Pipeline as Code』,『Infrastructure as Code』等概念。
  3. 3. 持续部署了之后呢? 这里会介绍 CD 结合团队的敏捷开发流程的实践经验。

microservices 概述

当提到 microservice 的时候,我们通常会从下图开始:
为了从业务和技术方面得到更好的扩展能力,我们将单一架构的系统(Monolithic architecture),拆分成若干的微服务(Microservices architecture),这种拆分是架构演进的一个过程。在整个拆分过程中,对团队的组织架构,数据的管理方式,部署监控技术方面都带来极大的挑战。持续部署(简称 CD)是 microservices 架构中一个必备的实践之一。本文将介绍基于Docker 的 CD 方式。

部署方面带来的挑战

单一架构下(Monolithic),我们的系统 Code base 可以在一个项目中,这个系统采用一个持续集成(简称:CI) pipeline,并且此时我们也可以采用持续集成(简称:CD)pipeline,最终将系统持续部署到生产环境中。在这种情况下,每当系统引入一个改变的时候,CI,CD pipe line 都会执行一次。例如:

  • - 10 mins Unit Test
  • - 2 hours Acceptance Test
  • - 15 mins package
  • - 20 mins deployment

上面列举的例子并不算坏,更庞大的系统可能会需要更多的时间。当我们将 Monolithic 系统拆分成多个 micro services 时,并且将每个 services 进行独立部署。每当系统引入一个改变的时候(code change),它只会影响个别 service,我们只需要部署发生改变的部署,从新运行一个 service 的 CI,CD pipeline:

  • - 1 mins Unit Test
  • - 1 mins Integration test
  • - 5 mins package
  • - 5 mins deployment

这种拆分之后,更符合我们对解耦的追求:『当代码引入一个改变的时候,它应该影响的改动最小』此时所提到的改变涉及整个开发流程,从代码到部署的影响做到了最小。拆分 services 之后的代价是,每个 service 都需要独立部署,我们需要为每个 service 搭建 CD pipeline。在 microservices 场景下,不同的 service 按照需求可能会采用不同的技术栈。并且在每次新建 service 时,配套的日志,监控,报警系统也需要进行配置。这个对 CD 提出了很大的挑战。

持续部署方面的实践

当我们谈持续部署的时候,此时也会包括持续集成。持续部署的整个过程会从代码 push 到 master 开始:
我们采用 Docker 来解决技术栈差异的问题,DevOps 创建部署工具将部署,监控,报警等配置模板化。实践:

  • - 使用 Docker 构建和发布 service
  • - 采用 Docker Compose 运行测试
  • - 使用 Docker 进行部署

准则:

  • - Build pipe line as Code
  • - Infrastructure as Code(base on AWS)
  • - 共享构建脚本

使用 Docker 构建和发布 service

  • - 使用 Docker 构建 service,service 已 docker image 的方式发布
  • - 将 docker 发布到 docker registry
  • - 从 docker registry 上 pull docker image 进行部署

使用 Docker Compose 运行测试

Docker Compose可以将多个 docker image 进行组合。有些 service 需要访问数据,我们可以通过 docker compose 将 service image 和 database image 组合在一起。组合之后,我们可以采用 docker compose 运行持续集成。下面这个实例展示如何进行这种组合:https://gist.github.com/lvjian700/7c295e6a596e96526049f831d0eb8b13#file-docker-compose-yml

Build pipeline as Code

通常我们使用 Jenkins 或者 Bamboo 来搭建 CI/CD pipeline,每次创建 pipeline 需要进行大量的手工配置,此时很难自动化 CI 服务器配置。Build pipeline as Code,即使用代码来描述 pipeline,这样做可以带来非常好的可读性和重用性。我们可以很容易的做到 CI 服务器配置。今年团队将所有 pipeline 从 Bamboo 迁移到了 BuildKite。在 BuildKite 上可以使用如下代码描述上图的 pipeline:https://gist.github.com/lvjian700/7c295e6a596e96526049f831d0eb8b13#file-buildkite-yml

Infrastructure as Code

如果我们要发布一个基于 HTTP 协议的 REST-ful API service,我们需要 service 准备如下基础设施(Infrastructure):

  • - 可部署的机器
  • - 机器的 IP 和网络配置
  • - 设备硬件监控服务(GPU,Memory 等)
  • - 负载均衡(Load Balancer)
  • - DNS
  • - AutoScaling (services 自动伸缩服务)
  • - Splunk 日志收集
  • - NewRelic 性能监控
  • - Sentry.io 和 PagerDuty 报警

这些基础设施的搭建和配置我们希望将其模板化,自动化。我们才用代码描述基础设施,DevOps 提供工具模板化基础设施的描述。实践:

  • - 采用 AWS 云服务进行部署
  • - 采用 AWS CloudFormation 描述和创建资源
  • - 将对资源操作的脚本进行 source control

准则:

  • - 对资源的描述和操作应该在 git 中
  • - 在所有环境中采用相同的部署流程
  • - 使用 ssh 等手动操作资源的方式,只能用于测试环境和做一些 debug。

共享构建脚本

在为多个 services 搭建 CD pipeline 之后,我们将 CD pipeline 归纳为三部:

  1. 1. 运行测试
  2. 2. 构建发布 docker image
  3. 3. 部署

分别为这三步提取出 shell scripts:

  1. 1. test.sh
  2. 2. docker-tag.sh
  3. 3. deploy <test|prod>

之后为上述脚本创建 git repository,并且将其以 git submodule 的方式引入各个项目。持续部署了之后呢?

让 CD pipeline 服务团队的工作流程

我们搭建好 CD pipeline,需要让它在团队的敏捷开发流程中发挥为威力:
团队职责:

  • - 团队主要分为 BA,Developer(简称 Dev),Tech Lead(简称TL)
  • - BA 负责分析业务,并在故事墙上创建 Story
  • - Dev 负责开发,QA,运维(跨能型团队)
  • - Tech Lead 负责技术

工作流程:

  1. 1. Dev 从 Backlog 中拿卡进行分析,分析完成后跟 BA,TL一起 kickoff 确定需求、技术实现。
  2. 2. kickoff 之后, Dev 在 repository 上创建 Pull Request(简称 PR) 开始工作。此时在 PR 上的每一次 git push 会触发 PR 的 pipeline,此时在 CI 机器上只会运行单元测试和集成测试。
  3. 3. Dev 开发完成后,其他 Dev 对 PR 进行 Review,Review 通过之后将 PR merge 到 master 分支,此时会 trigger master 分支上的 pipeline,将最新代码自动部署到 test 环境。
  4. 4. 部署 test 环境成功后,Dev 基于 test 环境进行 QA。
  5. 5. QA 完成后向 BA, TL 做 showcase 进行 user acceptance test。
  6. 6. 通过 user acceptance test 之后,在 BuildKite 上点击部署到 production 按钮完成发布。

按照以上流程,团队可以快速从 CI/CD pipeline 上得到反馈,高度自动化的 CD pipeline 可以让团队做到按照 Story 进行 service 发布。Summary

Microsservices 在业务和技术的扩展性方面带来了极大的便利,同时在组织和技术层面带来的极大的挑战。由于在架构的演进过程中,会有很多新服务产生,持续部署是技术层面的挑战之一,追求极致的自动化,可以让团队从基础设施抽离出来,关注与产生业务价值的功能实现。
Q&AQ1:你们的docker是用什么来管理的?k8s,swarm 还是其他什么?

A1: K8S, Swarm 都没使用,对这两个服务我也只是听说过。 每个独立的 service Docker image 会单独运行在 AWS EC 2 Instance。管理一般也都是围绕 EC 2 Instance 来做。关于  Docker Images 仓库,采用自建的 Docker Registry 服务来 push 和 pull docker image。================Q2:如何做跨语言的服务集成A2:  我们做过 Ruby 和 Node.js 的集成。服务器间通信采用 HTTP 协议,JSON 作为传输格式, JSON 基于 hyper media link 的实现之一 HAL 。  如何解决 service 之间的约定,我们采用 Consumer Driven Contract 的方式,使用单元测试代替集成测试,这部分实现采用 Pact 。================Q3:service的粒度如何确定A3: 这是一个非常好的问题,也是很难回答的问题。  我个人觉得 microservices 中最难回答的两个问题是:1. 什么拆分出一个 service?2. 怎么拆分?(也就是拆分多细,系统边界如何确定)service 粒度如何确定,一句话来回答(TL;DR):『采用领域驱动设计(DDD)的方式拆分』。更长版本,我们项目是为客户解决已运行10年以上财务生态系统的拆分问题。也就是老系统改造,也是我觉得最适合实施 micro services 的场景。老系统存在很多痛点,并且需求较为稳定。那么如何拆:1. 需要引入业务专家,技术专家,相关利益人一起分析业务场景,系统构成确定领域语言对业务进行建模。2. 将以前以业务切分系统的思路转为按照数据模型切分的思路。3. 每个类数据模型可以划分多种子模型来辅助主数据模型。4. service 的粒度一般以数据模型的粒度来确认。还有一些按照非功能性需求来切分的原则,比如实施 CQRS 的时候,将读写拆成两部分,采用 Even Sourcing 解决分布式系统数据状态同步的问题。================Q4:为什么没有考虑gocd,gocd可是first class的CI/CD工具A4:  好问题,这个我需要找 ThoughtWorks 负责 GoCD 的同时聊聊销售问题。BTW,我个人还没机会使用过 GoCD================Q5:目前发现从esb  soa转microservice,原本进程内的调用关系变成了网络调用,一次rpc变成了几次或者几十次rpc,同等条件下性能损失严重。这个问题如何得到解决?A5:  好问题,性能问题也是被同事问得最多的问题。关于性能问题我没遇见过高并发的场景,当时对于降低 services 依赖,控制网络请求我们是有一些解决方案。1. 所有 services 基本都部署在同一个网络,比如 AWS 的网络上,可以讲起想想成内部局网,HTTP call 带来的性能损耗目前为止还算可以接受。
2. 从系统设计的角度讲,与其降低HTTP请求的消耗时间,不如减少HTTP 请求的发送次数。从系统设计上考虑,大部数据模型都是 immutable (不可变得),在系统系统间我们将数据缓存,减少 HTTP 请求的次数。

时间: 2024-10-29 04:27:35

Microservices 场景下的持续部署 | 吕健的相关文章

通过Docker容器运行持续集成/持续部署

本文讲的是通过Docker容器运行持续集成/持续部署,[编者的话] 对于Docker主流的应用场景:持续集成和持续部署(CI/CD)大家也许并不陌生.这篇文章从独特的视角阐述了如何利用各种云平台构建属于自己的CI/CD容器,笔者还自己扩展了Gitlab CI引擎,对CI感兴趣的同学对这个文章应该很感兴趣. 我曾经使用Docker了一段时间,在过去的一年里伴随着众多的Docker容器涌入,帮助用户们更容易的部署Docker容器到生产环境中.一些工具是第三方公司提供,当然也包括Docker公司自己的

HiStore:阿里巴巴海量数据场景下的OLAP解决方案

摘要:7月27日,.阿里中间件举办了首届阿里巴巴中间件技术峰会,揭秘阿里10年分布式技术干货.在首届阿里巴巴中间件技术峰会上,阿里巴巴中间件技术专家焦方飞为大家分享阿里巴巴海量数据场景下的OLAP解决方案,此外还对阿里新推出的高性能时序数据库进行了简单介绍,精彩不容错过. 以下内容根据演讲嘉宾现场视频以及PPT整理而成. 本次分享的主题是阿里巴巴海量数据场景下的OLAP解决方案,主要是也为大家介绍一下阿里巴巴OLAP存储的一款产品--HiStore.大家都知道海量数据,包括大数据和数据仓库这些在

浅谈基于Ansible持续部署自动化

本文讲的是 :  浅谈基于Ansible持续部署自动化  , [IT168技术]随着各种计算机虚拟技术的不断发展,云计算的工业化水平也日渐成熟.在新的形势下,IT运维面临着来自各个方面的挑战,维护的机器数量从数十个几百个到成千上万个,应用的结构变得越来越复杂,更新的速度也越来越快.各种自动化配置管理工具也在这种生态环境中应运而生,如puppet,saltstack,ansible.本文将用ansible来具体讨论其在不同场景下的使用方法,从而使运维和开发人员更加轻松的应对各种配置管理及应用部署需

自动化持续部署的三种反模式及解决方案

自动化持续部署是业界最佳实践,以此为目标,能优化IT模式. 在接触的很多企业中,持续部署实践依然还有很多不足,基本上部署靠人,更别谈自动化了.我一直强调持续部署是IT交付的核心能力,直接关联到研发/测试和运维多个团队,可以成为一个运维的核心平台.自动化部署能力的高与低,能映射出IT能力的诸多方面的问题,比如说流程上/环境管理上/服务耦合上/平台能力上等等. 个人已经做了三个持续部署系统,每做一个持续部署系统都给整个IT团队带来巨大的收益.当带着这些经历再回过头去看<持续交付>这本书的时候,书中

利用Rational ALM工具使持续部署变得切实可行且具成本效益

然后他还解释了如何将用于 ALM 的特定 Rational 工具与云相结合,使持续部署变得切实可行且具有成本效益,因为持续部署可以减少测试和部署工作.改善治理并降低部署到生产环境中的风险. 什么是持续部署,为什么对它感兴趣,它有助于解决哪些问题? 对于许多组织来说,业务和http://www.aliyun.com/zixun/aggregation/7434.html">开发团队的愿望是更快.更频繁地生产可用软件,而运营团队的责任是以规避风险的方式管理组织的基础架构,从而确保业务的连续性,

端到端GPU性能优化在深度学习场景下的应用实践

摘要:在2017杭州云栖大会机器学习平台PAI专场上,阿里巴巴高级算法专家杨军结合具体案例分享了端到端GPU性能优化在深度学习场景下的应用实践.   本文内容根据嘉宾演讲视频以及PPT整理而成.   目前深度学习和GPU已经成为了人工智能的基础,一软一硬的结合能够帮助我们实现图像识别.语音识别以及视频的处理,那么如何优化深度学习框架与GPU资源也是机器学习平台的一个研究方向.   本次分享主要分为以下5个部分: 1.         背景介绍 2.         优化思考 3.        

国家“千人”王中风教授:如何满足不同应用场景下深度神经网络模型算力和能效需求

基于神经网络的深度学习算法已经在计算机视觉.自然语言处理等领域大放异彩.然而,诸如 VGG.ResNet 和 Xception 等深度模型在取得优越性能的同时往往伴随着极高的存储空间需求和计算复杂度,而现有的通用计算平台(如CPU和GPU等)很难实现高能效的神经网络计算.为了满足深度神经网络在不同的应用场景(如云端和终端)下的算力和能效需求,探讨如何在算法层面运用量化.剪枝等方法进行模型压缩,以及设计适应于不同应用场景的高能效神经网络计算芯片/架构已经成为学术界和工业界近阶段的一个研究热点. 目

不同场景下 MySQL 的迁移方案

一 目录 一 目录 二 为什么要迁移 三 MySQL 迁移方案概览 四 MySQL 迁移实战 4.1 场景一 一主一从结构迁移从库 4.2 场景二 一主一从结构迁移指定库 4.3 场景三 一主一从结构双边迁移指定库 4.4 场景四 一主一从结构完整迁移主从 4.5 场景五 双主结构跨机房迁移 4.6 场景六 多实例跨机房迁移 五 注意事项 六 技巧 七 总结 二 为什么要迁移 MySQL 迁移是 DBA 日常维护中的一个工作.迁移,究其本义,无非是把实际存在的物体挪走,保证该物体的完整性以及延续

高效运维之Docker持续部署图文详解

前言 关于Docker的文章铺天盖地,但精品文章往往翻译居多.都说Docker天生适合持续集成/持续部署,但同样,可落地.实际可操作性的文章也很少见. 基于这些情况,虽然我们专栏定位为运维管理性文字,但本篇是个特例,实操性的案例讲解--JAVA项目如何通过Docker实现持续部署(只需简单四步),即: 开发同学通过git push上传代码,经Git和Jenkins配合,自动完成程序部署.发布,全程无需运维人员参与. 这是一种真正的容器级的实现,这个带来的好处,不仅仅是效率的提升,更是一种变革: