导读
系统架构是一个系统的灵魂,然而一个好的架构(或者更确切的说,一个合适的系统架构)不是一蹴而就,一会儿就能彻底设计出来的,而是随着系统发展,逐步演进的。本文将介绍明源云研发协同平台的架构从0到1,逐步随着业务发展一步一步迭代演进的过程。linux
背景
随着公司的ToB业务发展,开发团队规模不断扩大,须要交付的业务也不断增加,在这个过程当中,交付的效率和质量出现了不一样程度的问题,虽然也有QA团队制定的流程规范以及一些相应的保障措施,可是在交付压力下,效果不那么尽如人意。在此背景下,研发协同产品被提上日程,最初的目的就是为了提高整个交付链条的效率和质量。研发协同平台提供从“需求->开发->构建->代码质量->测试→发布”的全链路的一站式服务,基于敏捷研发、持续集成、持续交付、DevOps等研发理念,主要是为开发团队赋能,提高交付效率和质量。webpack
技术选型
技术选型是一个项目的基础,一旦技术选型出现问题,后期要换用其余技术栈,代价是很是大。通常状况下,技术选型会遵循如下几个原则:web
- 选择熟悉的技术 - 一个新项目最好不要使用超过 30% 的新技术,对于不谁的技术,不可能控制使用过程当中出现的风险。并且从团队建设上,任何一位技术 Leader,若是不能获得下属的技术尊重,必将受到惩罚。固然也不能彻底不用新技术,彻底不用,势必会走向走向另外一个极端,裹足不前,失去技术前进的机会。总的来讲,选择熟悉的技术,保持稳定性,同时适当引入新技术,保持技术先进性。
- 选择成熟活跃的技术 - 选择成熟的技术,能够避免踩没必要要的坑,碰到问题,也能够找到丰富的资料,也能够获得更多的社区支持。固然这是针对应用场景而言,也有一些团队专门就是作新技术预研,专门去踩坑,看是否有应用新技术的可行性。技术不光是考虑成熟度,还要考虑技术活跃度,活跃度在某个角度也间接说明了技术的应用广度,同时也能获得更多的支持。
- 选择前进的技术 - 选择一个技术的最低标准是,技术的生命周期必须显著长于项目的生命周期。为何须要确保所选择的技术不断前进?由于当前技术发展是很是快速的,技术的前进不只仅取决于它自己,也和大环境发展密切相关。例如早期的delphi, silverlight, 如今都已被淘汰,若是不幸选择了相似这样的技术栈,对项目的伤害是巨大的,甚至可能直接致使项目没法进行下去。总的来讲,好的技术栈要永远跑在用户需求前面。
基于以上的技术选型原则,研发协同平台的技术选型以下:redis
- 应用技术选型:.Net Core, ABP, EF Core,SQL Server
选型理由:团队开发人员都是.NET开放背景,.Net Core 2.0已发布,已经比较成熟稳定,相较于.Net Framework,不只跨平台,并且开源,社区活跃度至关高。ABP是一个开源的.NET/.NET Core的基于DDD的快速应用开发框架,社区活跃度高,版本迭代快,一直在向前。最重要的一点,是这些技术栈都有团队成员有成功的实施经验。
- CI/CD工具链技术选型:
需求管理 - JIRA
代码托管- Gitlab, sourcetree
持续集成 - Jenkins, webpack, grunt
持续部署 - docker
质量服务 - sonarqube, dotcover, nuint, xunit, jmeter,selenium
选型理由:团队除了在docker上的应用经验有所不足外,其余的技术都是很是成熟的。docker技术,团队虽然也有必定的技术基础和应用经验,但没有像研发协同这种大规模的生产应用,而且要同时支持windows和linux容器。研发协同平台的产品特性决定了,会有大量开发团队的测试环境运行在平台下,docker是最符合产品需求的技术。因此即便有风险,也必须选择docker,同时也是必须啃下的骨头。
单体架构
在项目初期,为了产品快速上线、快速验证,架构是比较简单直接的,就是单体架构,以下图:
docker
单体架构实现了主要的核心功能,提供了一站式的从需求->代码管理->开发->持续集成的服务。总体架构就是展现层->应用服务->数据层,其中缓存,后台做业,调度,邮件,日志,权限控制等都是以功能模块的形式内嵌在应用服务中,对于在CI过程使用到的工具栈,也是直接调用第三方的服务。另外由于CI过程通常都是长时任务,对于在展现层显示CI的过程状态,也是采用了简单的轮询机制来处理。
单体架构快速了实现了产品的核心功能,能够提供给种子用户快速验证,但随着验证反馈->快速迭代,一旦产品提供给大范围的用户使用,这种架构也就不在知足需求了,它的主要问题以下:windows
- 业务服务和基础功能服务耦合在一块儿,一方面影响业务服务的扩展,另外一方面基础服务是公共的,除了为RDC平台提供服务,在技术上也须要为其它产品提供服务
- 业务服务中有很多长耗时的任务,这些都影响了业务服务的横向扩展,长耗时任务也必须从业务服务解耦
- 轮询机制的状态刷新须要改进,同时应用服务和基础服务拆分后,也须要机制保障通讯,缺乏消息服务中间件
- 无论是从稳定性仍是可用性考虑,服务都必须可扩展
- 一旦大范围使用,Jenkins单点,docker单点服务,都不足以应对,必定要集群
面对上述问题,平台的架构也必须升级来知足业务业务发展的需求,而演进的主要方式则是服务化、集群化缓存
架构演进的五条原则
既然要对架构进行升级重构,那么有没有一些基本的准则,指导咱们避免一些坑呢?基于此,咱们尝试总结了架构演进的五条原则:安全
- 肯定当前的架构现状:每次架构演进,必定是针对当前架构的,因此必须很是清楚当前的架构现状和问题。清楚现状,明白目标,才能逐步改进,向目标前进。
- 肯定重构的目的和必要性:架构重构的缘由是什么?是为了知足业务须要仍是只是以为架构比较落伍?除了架构重构以外,是否有别的备选方案,是否必定要进行架构重构?
- 定义“重构完成”的标准:为每一次架构演进定义清晰的重构目标和成功标尺。
- 渐进式重构:尽可能将重构过程进行分解,每次都进行小的改进,尽快展现成果并获得反馈,在迭代中逐步完善。
- 远离虚的东西:例如使用热门的技术,使用不成熟的技术。架构重构要脚踏实地,根据实际须要以及团队的技术背景,合理的选择重构方案。
咱们每次对架构的重构,都是按照这些原则来进行的。服务器
向集群架构演进
单体架构有很多问题,可是否必定须要进行架构重构呢?在重构前,咱们须要回答架构演进原则提出的问题:架构
- 肯定当前的架构现状:全部服务集中在一块儿运行。
- 肯定重构的目的和必要性:随着产品的逐步推广,使用用户增多,使用频率,单体架构在应对业务量上涨上已经愈来愈吃力,同时,可用性也成为了高风险点。
- 定义“重构完成”的标准:让架构支撑服务化,集群化。
- 渐进式重构:以迭代的方式,按优化级逐步重构。例如,jenkins集群化,docker集群化,基础服务解耦服务化,一步一步,每一步均可以看到效果,获得反馈。
- 远离虚的东西:并无引入多少新的东西,主要是解耦,服务化,集群,增长消息服务中间件。
除了原有的架构重构外,在产品层面, 整个交付链条延伸到了C/D环节,这里和其余DevOps平台一个很不同的点就是,在研发协同平台上交付的产品是ERP产品,ERP产品是运行在大量客户的不一样环境下的,它不是交付一个SaaS产品,一个云服务产品。ERP产品要持续交付给大量的不一样客户,而这里的客户环境又各不相同,要作到稳定,持续的交付是有至关大的难度和挑战的,在架构设计上必须充分考虑C/D的稳定性和持续性。
基于以上的需求,咱们将单体架构重构为集群架构,并增长了C/D的架构设计,架构图以下:

集群架构有以下特色:
- 解耦了基础服务与业务服务,各个服务的职责更清晰,也更单一
- 基础功能服务化,复用基础服务能力
- 使用Azure文件云服务,提升文件服务的可靠性和可用性
- 新增消息服务,解耦各组件之间的通讯
- 构建服务集群,提升服务的可靠性和可用性
- 构建Jenkins集群,提升平台的持续集成能力
- 构建docker服务集群,提升平台持续部署,持续提供稳定运行环境的能力
实现了集群架构之后,服务的能力,稳定性和可靠性都上了一个台阶,可是随着用户的使用愈来愈深刻,平台提供的服务愈来愈多,集群架构的问题也逐步开始显现:
- 平台提供的服务能力愈来愈多,业务愈来愈复杂
- 服务虽然集群化,可是业务服务能力仍是单一对外,某个服务功能出现问题,会影响到服务总体对外提供的能力。可行的途径是进行服务拆分,不过服务拆分,复杂度也会增长,服务的运维成本以及治理问题也是须要综合考虑的
- docker容器采用自开发的集群分配策略,缺乏编排能力
- 平台服务要提供集成与被集成的能力,与其余的CI服务集成,与测试平台集成
- 平台要与其余产品打通 - 与运维产品打通,获取客户运维数据,作到DevOps闭环,经过反馈和运维数据反向推进产品持续迭代改进
- 平台要对外开放,面向生态合做伙伴提供服务能力,对外开放,第一步就是要让用户能进来,这就涉及到整个用户中心体系的创建,用户管理、统一身份认证等。
- 虽然集群架构已大大提升了可靠性和可用性,可是随着服务的深刻使用和用户规模的不断增加,对可靠性和可用性的要求也愈来愈高,对平台服务以及服务资源的运维也变得愈来愈重要和紧迫
面对上述问题,须要对服务进行拆分,治理,提供服务和资源的运维、监控能力,而都须要架构
向微服务架构演进
在进行微服务架构重构以前,咱们一样须要回答架构演进原则提出的问题:
- 肯定重构的目的和必要性 - 随着产品的持续迭代,业务复杂度愈来愈大,服务的使用也愈来愈深刻,用户规模也在不停的增加,对总体服务的可靠性,可用性提出了新的挑战
- 定义“重构完成”的界限 - 微服务化,容器云平台
- 渐进式重构 - 以迭代的方式,按优化级逐步重构。例如服务的运维,监控,日志服务,服务的拆分,治理,容器云平台这些都是独立可逐步改进的
- 肯定当前的架构状态 - 集群架构中已经详细的描述
- 远离虚的东西 - 新引入的技术点都有成熟可借鉴的方案,例如k8s,ELK,grafana, IdentityServer4,Ocelot,Consul
可是这里有一点是要特别强调的,尽管新引入的技术都有成熟可借鉴的方案,可是对团队而言,有很多是没有成功的生产环境实施经验的,这里是冒了必定的风险,但又是不得不去作和突破的事情。
重构后的微服务架构图,以下:

微服务架构的特色以下:
- 提炼CI引擎,丰富集成能力
- 服务按领域拆分,提供服务治理能力
- 服务运维能力,提供监控、告警、统计分析
- 提供日志服务,便于错误分析和运营分析
- 提供统一的容器云服务, 提供高可用、可伸缩的容器应用管理
各个应用层在微服务架构下的职责:
- 运行环境层:提供基础设施服务,包括服务器,IT安全配置以及容器云平台。将来全部的服务都会运行在容器云平台上,当前只有少数的服务在容器云平台上试运行,随着不断的改进、成熟,将来会逐步将服务迁移到容器云平台上
- 数据存储层:提供数据存储能力,对于不一样的数据类型,提供了不一样的存储方式。 Sql Server用于应用数据的存储,redis用于缓存数据的存储,ES集群用于日志的存储,Azure文件用于文档的存储
- 基础服务层:提供基础公共服务能力,除了为研发协同平台自己提供基础服务,也面向其余产品提供基础服务能力。
日志服务(ELK)提供日志采集,存储,分析和展现服务;
消息服务(MQTT)提供组件间的通讯能力;
文件服务(Azure文件)为应用提供统一的上传、存储、下载的服务;邮件服务提供邮件发送服务;
任务调度和后台做业(Quaz+Hangfire)提供了长耗时任务队列的调度和处理服务;
身份认证服务(IdentityServer4)面向开放提供了统一的身份认证能力。
- 应用服务层:研发协同业务服务,主要包含基础服务,产品服务,持续集成服务、质量服务和持续交付服务。当前应用服务尚未微服务化,还处于服务拆分阶段,按领域拆分,按文件结构组织,一旦微服务框架就绪,则按领域服务一个一个拆分,逐步切换。
- API接口层:API网关为服务消费端提供了统一的服务入口。除了网关,实现微服务框架,还必须实现服务治理:服务的注册、发现、负载、容错、降级、监控与日志。
- 展现层:展现层是应用服务的消费者,经过API网关来使用应用服务。
- 运维监控:运维监控服务(App.Metric+telegraf+InfluxDB+Grafana)当前主要实现了服务器资源监控以及业务服务的监控(流量、请求、错误等),以及分析图表的展现,并根据必定的预警规则,即便预警异常。
微服务架构是咱们今年技术规划要实现的目标,其中一部分已经落地,一部分正在进行,也有一些还未开始,随着产品业务的发展,伴随着架构也是在不断摸索、重构、演进、向前。
写在最后
历来没有一个完美的架构可以一直支撑业务的发展,架构是动态的、变化的,随着业务的发展不断演进的,不一样的阶段须要不一样的架构 。研发协同平台的架构也是经历了单体架构->集群架构->微服务架构几个阶段,并且每一次架构重构周期都比较长,只要架构的模式思路定下来,保持快速的敏捷演进,不停向前,结合反馈和实际应用状况,不断改进,就能够比较稳定的实现架构重构。