项目介绍
三拾众筹是一个创新型的业务,我们的理想是做不一样的众筹平台:
基于内容产品提供众筹服务
专注探寻最有创意的想法、最有温度的故事
深耕影视、游戏、音乐、传媒、动漫等泛文娱领域
从2016年7月份项目筹备,经过两个多月的开发,10月份平台正式上线运营。我们的口号是:再小的力量,也能掷地回响。
时间线
在运行一个创新业务的时候,我们的技术会面临很大的挑战,这和我们创新业务的特点是有关的:
第一:业务是快速变更的,不可能想好的所有的事情才开始启动我们的项目,所以刚开始的时候,所谓的创新更多的是在试错,我们希望项目在做的时候,不断地收集反馈,不断地调整方向,最终找到突破点。在不断调整方向的过程中,技术必须做到及时响应。当业务需要技术提供弹药的时候,技术不能说我们还在调研,我们还在建厂房,功能不能变更。
第二:业务爆发式的增长。前面说我们去找方向,什么是正确的方向,很难去判断,但是至少我们不是为了维持某种状态去做的,因为我们是一个从无到有的过程。一旦我们找到了正确的方向,接下来业务就会出现一个提升或者扩张,但是时间是无法预期的,往往是爆发式的,很难线性的去判断。但是对于技术来讲,如何能够不拖业务爆发的后腿,是一个棘手的问题。当业务有很大的流量导入的时候,我们的系统不能撑不住,挂了。
第三:资源成本投入。所有的创新项目资源都是有限的,如果资源很多,往往就没有了创新的土壤。资源不多就必须将有限的资源用在刀刃上。
需求
面对这三项挑战,我们的技术团队必须具备三项技术能力:
-
快速迭代:产品要快速交付,快速部署。
-
可扩展:系统能够通过横向扩展的方式,支撑更大的流量
-
技术有按需的能力,只扩展应该扩展的模块。
这让我们这个创业团队想要借助云的力量,借助 易云容器平台的力量。
对于云来讲,按需的能力是天然的,在 易云上,我们是按需按时分配的。而快速迭代和可扩展,是云的潜力,使得我们不需要采购机器,安装系统,部署环境。
那三拾众筹如何才能发挥云的潜力,如何设计我们的系统,使用什么样的开发过程,才能让云真正的帮助我们的业务?
这里有一个重要的概念,就是Cloud Native。有人之前翻译为云原生应用,我觉得比较直白,我起了一个小清新的名字,叫做向云而生。
这表示我们的应用应该设计为面向云和容器平台去应用的。
设计目标
使用标准化流程自动配置(declarativeformats for setup automation),从而使新的开发者花费最少的学习成本加入这个项目。
和操作系统之间尽可能的划清界限,在各个系统中提供最大的可移植性。
适合部署在现代的云计算平台,从而在服务器和系统管理方面节省资源。
将开发环境和生产环境的差异降至最低,并使用持续交付实施敏捷开发。
可以在工具、架构和开发流程不发生明显变化的前提下实现扩展。
另外还有12原则
三拾众筹是非常相信12原则,把整个系统按照12原则进行设计。
12 Factors
-
Codebase-One codebase tracked in revision control, many deploys
-
Dependencies-Explicitly declare and isolate dependencies
-
Config-Store config in the environment
-
Backing services-Treat backing services as attached resources
-
Build, release, run-Strictly separate build and run stages
-
Processes-Execute the app as one or more stateless processes
-
Port binding-Export services via port binding
-
Concurrency-Scale out via the process model
-
Disposability-Maximize robustness with fast startup and graceful shutdown
-
Dev/prod parity-Keep development, staging, and production as similar as possible
-
Logs-Treat logs as event streams
-
Admin processes-Run admin/management tasks as one-off processes
系统架构
服务架构
三拾众筹的架构采用的是服务化的架构,是由一系列相互协同的服务组成的。服务之间有协作的过程,服务对外也提供了统一的界面。每一个服务本身有自己的存储,有自己的缓存。
所有的服务分两个区域,也即服务分两种类型。第一是应用的服务,第二是基础服务。
在应用服务里面,对外有一个主站服务,同时承担了API 关的职责。他会把前台的请求分发到后台,并且根据规则进行路由。
服务与服务之间都是通过Restful API也即HTTP的方式,服务之间会有明确的依赖关系,而且依赖关系的强弱在这里用实线和虚线做区分。通过这些依赖关系来构成和编排我们的服务。
我们最初上线的平台也不是这样的,而是只有一个众筹平台。是随着功能的丰富,应对更快的变化,而逐渐拆分的,例如对于支付模块,当我们需要接入更多的支付方式,针对支付有更多的优化需求的时候,我们需要独立出一个收银台的模块,进行服务拆分。包括会员,包括订单的部分。
为了支撑应用服务的环境,我们还有一些基础设施服务。
比如注册中心,服务之间有自动的服务注册与服务发现的机制。我们的所有服务是通过注册中心进行相互关联的,不需要人工的编排,是可以自动的发现服务。
我们可以通过服务的控制台去管理服务。我的服务状态是什么,对应的版本是什么。
每个应用都涉及到一些配置参数,如果配置参数扔在每个服务上的话,对于运维来说代价比较高了。对于微服务架构来讲,必然需要一个集中化,可分发的配置中心,也是在基础服务中的。
我们会使用Git仓库作为配置的后端,通过配置中心去分发Git仓库中的配置,同时后面我们还会提到,有一个流程来管理整个过程。
在这个架构里,所有的组件都在容器里面。每个服务构建的结果就是镜像,在运行期就体现为容器。
这里面的每个服务都使用的是 易云的无状态服务,除了构建服务,构建服务是从代码构建为镜像,是在我们自己的服务器上运行,也是一个容器。
设计要点
接下来我分享一下我们的设计时的考虑及实现要点:
第一.Cloud Native的设计
-
从设计开始,我们就隔离了基础设施和后端服务依赖,这个隔离一方面是由容器来做的,隔离了应用和服务器之间的关系,隔离另一方面,应用层我们用了很多的框架,例如我们后面提到的springboot和springcloud,我们使用公共的开源的框架和工具,把一些面向服务化,容器化的基础功能进行实现,对于应用本身不需要关系这些过程,他只需要关注中间层,根据spring的规约来进行开发。
-
从一开始,就把配置和代码进行分离。将配置和镜像进行分离。
-
对于编排的问题,通过springcloud和consul进行服务发现的功能,来实现服务的自动编排。
第二,容器化的实践
-
广泛使用了容器,在我们看来,容器就是服务。当我们实现一个新功能的时候,首先要考虑需不需要单独拆分为一个新的服务。
-
通过提供一批基础镜像,来简化服务的开发,可以说是应用开发的模板
-
使用了 易云基础设施平台,因为他非常开放,技术导向,对程序员友好。提供了丰富的API,通过这些API可以实现自动化,实现自动交付。另外蜂巢提供了很多基础PaaS服务,包含数据库,缓存,CDN,对象存储,负载均衡等,降低构建服务的难度,提高开发效率。我们几乎用了所有的PaaS服务,使得我们不必要过多关心平台层面的东西。
第三,微服务基础设施
-
服务的注册,发现和负载均衡机制。这个机制目前是通过spring cloud来做的。Spring cloud是一个非常完整的微服务开发的框架,他的主要作用是在应用和设施之间提供一个抽象层,让我们用一致的API去使用不同的服务发现的机制,比如基于Java开发的eureka,包括我们使用的consul。
-
我们实现了配置中心
-
我们实现了服务控制台,可以查看各个服务的状态,以及获取服务状态变更的消息通知,还有对于服务端点Endpoint本身进行管理。对于微服务架构来说,每一个服务的端点Endpoint应该更加智能,这是和SOA的区别,我们也是这样的,对于每一个服务,我们借助springcloud提供的一系列管理端口,我们的服务控制台可以通过这些管理端口去控制他,包括去查看和修改某一个服务节点的配置,查看某个节点的日志,都是可以通过服务控制台去实现的。
镜像构建
为了尽量降低服务本身和基础设施之间的关联,在构建基础镜像的时候,分成几个层次去考虑。
-
最里面的一层,是OS和系统工具的一层,我们是基于Debian系统进行构建。
-
应用环境的部分是和应用分离出来的,包括JDK,consul服务发现的机制等,这里有个小工具dumb-init,可以实现在一个Docker里面实现多进程。如果在Docker里面使用多进程会有一个比较大的坑,如果某个进程死掉,他的子进程就会变成僵尸进程,没有办法收回,导致我们关闭Docker容器的时候是需要强制杀掉的,这对于程序需要优雅关机来说是很有问题的。Dumb-init可以解决这个问题。另外dumb-init可以实现信号的重写。比如有些应用是需要接收一些信号,比如ctrl+C才能结束的,为了响应SIGINT信号,可以通过dumb-init进行转发。
-
在应用层的Dockerfile会非常的简单,选择一个正确的基础镜像,然后把包打进去就可以了。
基于Gitflow代码管理和协作流程
Gitflow是一个代码管理的流程,我们基于他实现了一个协作的流程。这个协作的流程体现在我们如何去发布我们的新版本,如果修改线上的Bug,如果进行开发,怎么集成测试,最重要的是怎么去验证,验证什么东西。整个过程需要自动化,整个过程都是通过gitlab-ce提供的界面,最重要的两个界面是Merge Request和自动化Pipeline来做的。所有的问题修改,所有的提测,都是通过gitlab-ce的Merge Request界面进行操作的。一旦Merge Request接受之后,都会有一个跟在后面的Pipeline,一个持续集成或者持续发布的任务,来完成后续工作,这些后续工作就是我们交付的流程。
我们使用两个蜂巢的环境,来作为开发和测试环境以及线上环境。对于特定的环境,我们自动构建和发布之后,会自动的进行部署,对于开发人员,QA人员,甚至线上预发环境的运维人员来说,他们只需要在Gitlab里面操作完了,相应的版本就构建上去了,这些版本都会在镜像仓库中,会对应我们的分支,会有独立的版本。我们还可以按需的去部署更多的环境,去进行检验,比如线上的扩展验证。
如图所示,左上角为提交的Merge Request,右面为Merge Request的详情,如果点击Accept Merge Request就会触发左下角的Pipeline进行整改发布流程。
整个交付流程如图所示:
-
开发有一个主分支称为develop,但是所有功能的开发都不在develop上开发,而是新开分支进行开发,可以根据发布的时间点确定某个功能是不是要上线,例如图中在这一版中,feature x, y可以上线,于是Merge到develop分支,而feature z赶不上这一版,会在以后的版本上线,所以暂且不Merge到develop分支。
-
Feature x,y合并develop分支需要经过Code Review,一旦合并后,会触发自动构建镜像的Pipeline,然后自动部署develop环境。开发需要在这个环境里面做集成和基本的测试,包含单元测试和冒烟测试,当集成和基本的测试遇到缺陷的时候,需要回到feature所在的分支进行缺陷修复,修复后重新Merge到develop,从而重新部署develop环境。当开发任务代码质量可以达到的时候,方才提测到QA。
-
有一个Release分支用于做测试验证,提测的发起是由develop分支Merge到release版本实现的。每次做release的时候,首先会从Master分出一个版本到release,Master分支的版本是当前的线上版本,则Develop Merge到release,其实是和线上版本的一个合并,保证当前的开发版本和线上版本可以兼容。这次Merge会触发Pipeline构建镜像,并且自动发布release环境,QA可以对这个环境进行自动化测试,或者手工测试,保证代码可以达到发布的质量。如果测试出现缺陷,则需要回到feature所在的分支进行缺陷修复,修复后重新Merge到develop,从而重新部署develop环境,在develop环境测试完毕后,再次Merge到release,然后QA再测试,如此反复,直到可以达到上线标准。
-
一个release分支可以达到上线标准,则将release分支合并回master分支,这次Merge会触发Pipeline自动构建镜像,自动部署预发环境。线上运维人员可以对预发环境进行测试。
-
如果预发环境没有问题,线上运维人员可以从镜像手工部署两套线上环境中的一套,如图中Online A和Online B,做灰度发布,新老版本先更新其中一套环境,然后前端通过负载均衡器将请求不断的从老版环境切换到新版环境。
-
如果需要性能测试,性能测试人员可以手工从镜像部署一套性能测试环境进行测试。
-
如果线上发现缺陷,则需要从Master上分出一个分支到hotfix,hotfix修复完毕进行测试后需要合并到Master分支,同时需要合并代码到develop分支。
配置管理
如图是一个配置管理的流程,
所有的配置文件都放在代码仓库Gitlab里面,进行代码级别的管理。
在Gitlab界面里面,点击accept进行代码合并,合并后触发webhook,调用配置中心。
Git2Consul从Gitlib中pull所有的配置文件,并且将配置文件的内容通过consul的客户端同步到consul中。
Profile=A的app和Profile=B的app通过consul的客户端将配置从consul中配置到服务中,完成配置的管理。
总结
最后总结一下:
首先,最大化利用开源工具和云端技术建立微服务和敏捷基础设施,构建Cloud Native 应用,充分释放云的潜力
其次,基于容器技术自动化构建、发布和配置流程,改进敏捷交付环境和产品快速迭代能力,及时有力支撑业务。
自10月27上线以来,三拾众筹系统(不包括基础服务)发布版本1710次,其中43次线上版本发布;发布线上配置33次,新系统设计到上线1 ~ 3周。
最后,通过实践打磨的方案才能适合自己,开放性是选择云平台关键评估因素。
福利
易蜂巢代金券兑换码:Z3710E6GADV3
登录 易蜂巢,使用兑换码兑换即可获得20元代金券!
声明:本站部分文章内容及图片转载于互联 、内容不代表本站观点,如有内容涉及侵权,请您立即联系本站处理,非常感谢!