本文来自三拾众筹系统架构师陈晓辉的演讲,题为“持续交付开发流程支撑创新业务”,介绍了三拾众筹基于网易蜂巢的系统开发实践。现将分享内容整理如下:
三拾众筹是一个创新型的业务,我们的理想是做不一样的众筹平台:
从2016年7月份项目筹备以来,经过两个多月的开发,10月份平台正式上线运营。目前的团队规模不大,属于内部创业的状态,但是我们的口号是:再小的力量,也能掷地回响。
今天的分享是从技术角度介绍一下我们如何构建这个持续开发的流程,来支撑我们的创新业务。
在运行一个创新业务的时候,我们的技术会面临很大的挑战,这和我们创新业务的特点是相关的:
面对这三项挑战,我们的技术团队必须具备三项技术能力:
这让我们这个创业团队想要借助云的力量,借助网易云容器平台的力量。
对于云来讲,按需的能力是天然的,在网易云上,我们是按需按时分配的;而快速迭代和可扩展,是云的潜力,使得我们不需要采购机器,安装系统,部署环境。
那三拾众筹如何才能发挥云的潜力,如何设计我们的系统,使用什么样的开发过程,才能让云真正的帮助我们的业务?
这里有一个重要的概念,就是 Cloud Native。之前有人翻译为云原生应用,我觉得比较直白,我起了一个小清新的名字,叫做向云而生。
这表示我们的应用应该设计为面向云和容器平台去应用的。
三拾众筹非常相信12原则,把整个系统按照12原则进行设计。
12 Factors
I. Codebase-One codebase tracked in revision control, many deploys
II. Dependencies-Explicitly declare and isolate dependencies
III. Config-Store config in the environment
IV. Backing services-Treat backing services as attached resources
V. Build, release, run-Strictly separate build and run stages
VI. Processes-Execute the app as one or more stateless processes
VII. Port binding-Export services via port binding
VIII. Concurrency-Scale out via the process model
IX. Disposability-Maximize robustness with fast startup and graceful shutdown
X. Dev/prod parity-Keep development, staging, and production as similar as possible
XI. Logs-Treat logs as event streams
XII. Admin processes-Run admin/management tasks as one-off processes
如图是三拾众筹的系统概览,也是我们当前系统的部署架构
三拾众筹的架构采用的是服务化的架构,是由一系列相互协同的服务组成的。服务之间有协作的过程,服务对外也提供了统一的界面。每一个服务本身有自己的存储,有自己的缓存。
所有的服务分两个区域,也即服务分两种类型。第一是应用的服务,第二是基础服务。
在应用服务里面,对外有一个主站服务,同时承担了 API网关的职责。它会把前台的请求分发到后台,并且根据规则进行路由。
服务与服务之间都是通过 Restful API也即 HTTP的方式,服务之间会有明确的依赖关系,而且依赖关系的强弱在这里用实线和虚线做区分。通过这些依赖关系来构成和编排我们的服务。
我们最初上线的平台也不是这样的,而是只有一个众筹平台。是随着功能的丰富,应对更快的变化,而逐渐拆分的,例如对于支付模块,当我们需要接入更多的支付方式,针对支付有更多的优化需求的时候,我们需要独立出一个收银台的模块,进行服务拆分。包括会员,包括订单的部分。
为了支撑应用服务的环境,我们还有一些基础设施服务。
比如注册中心,服务之间有自动的服务注册与服务发现的机制。我们的所有服务是通过注册中心进行相互关联的,不需要人工的编排,是可以自动地发现服务。
我们可以通过服务的控制台去管理服务。我的服务状态是什么,对应的版本就是什么。
每个应用都涉及到一些配置参数,如果配置参数扔在每个服务上的话,对于运维来说代价就比较高了。对于微服务架构来讲,必然需要一个集中化,可分发的配置中心,也是在基础服务中的。
我们会使用 Git仓库作为配置的后端,通过配置中心去分发 Git仓库中的配置,同时后面我们还会提到,有一个流程来管理整个过程。
在这个架构里,所有的组件都在容器里面。每个服务构建的结果就是镜像,在运行期就体现为容器。
这里面的每个服务都使用的是网易云的无状态服务,除了构建服务。构建服务是从代码构建为镜像,是在我们自己的服务器上运行,也是一个容器。
接下来我分享一下我们设计时的考虑及实现要点:
蜂巢
• 集群和容器、镜像仓库
• RDS、缓存
• 负载均衡、对象存储
服务模板
• consul
• spring boot/cloud
• Rest RPC: spring mvc, feign, ribbon,(客户端的负载均衡)
• nginx (外部 HTTP请求的转发), consul-template (配置和配置中心打通)
• dumb-init (Docker里面运行服务的工具)
持续集成
• Gitlab-CE (私有代码仓库,协作流程和配置管理的入口)
• docker、maven
• flyway, junit, h2, mockito, spring test (持续集成的关键点是自动化的验证)
为了尽量降低服务本身和基础设施之间的关联,在构建基础镜像的时候,分成几个层次去考虑。
Gitflow是一个代码管理的流程,我们基于它实现了一个协作的流程。这个协作的流程体现在我们如何去发布我们的新版本,如果修改线上的 Bug,如果进行开发,怎么集成测试,最重要的是怎么去验证,验证什么东西。整个过程都需要自动化,且都是通过 gitlab-ce提供的界面。最重要的两个界面是 Merge Request和自动化 Pipeline来做的。
所有的问题修改,所有的提测,都是通过 gitlab-ce的 Merge Request界面进行操作的。一旦 Merge Request接受之后,都会有一个跟在后面的 Pipeline,一个持续集成或者持续发布的任务来完成后续工作,这些后续工作就是我们交付的流程。
我们使用蜂巢的两个环境,来作为开发和测试环境以及线上环境。对于特定的环境,我们自动构建和发布之后,会自动地进行部署,对于开发人员,QA人员,甚至线上预发环境的运维人员来说,他们只需要在 Gitlab里面操作完了,相应的版本就构建上去了,这些版本都会在镜像仓库中,会对应我们的分支,会有独立的版本。我们还可以按需去部署更多的环境,去进行检验,比如线上的扩展验证。
如图所示,左上角为提交的 Merge Request,右面为 Merge Request的详情,如果点击 Accept Merge Request就会触发左下角的 Pipeline进行整改发布流程。
整个交付流程如图所示:
如图是一个配置管理的流程。
所有的配置文件都放在代码仓库 Gitlab里面,进行代码级别的管理。
编辑配置文件 app.properties和 app-A.properties,然后提交,通过 Merge Request提交到 Gitlab里面。
在 Gitlab界面里面,点击 accept进行代码合并,合并后触发 webhook,调用配置中心。
Git2Consul从 Gitlib中 pull所有的配置文件,并且将配置文件的内容通过 consul的客户端同步到 consul中。
Profile=A的 app和 Profile=B的 app通过 consul的客户端将配置从 consul中配置到服务中,完成配置的管理。
最后总结一下就是: