公有云SAAS产品不同于传统的软件包产品,我们不仅需要负责软件的研发,同时需要负责产品的运维,面对众多用户,需要保障产品7X24不间断运行;客户业务是不断变化的,产品需要在持续运行过程中进行持续升级,以满足客户业务不断变化的需要。相对传统软件包产品,公有云产品的升级更加复杂,风险也更高,类似于在运动的汽车上更换轮胎。
设计的本质就是让产品变化更容易。微服务架构是互联网时代以适应快速的业务变化而产生的一种架构模式,提供了让变化更容易的基础。自2014年起开始得到业界的广泛关注,近几年,随着DevOps技术的成熟,微服务架构模式得到越来越多企业的实践应用。微服务架构的特点是能够独立开发独立部署,独立伸缩和独立运维,技术上没有免费的午餐,微服务在给我们带来众多好处的同时,也带来了众多的复杂性,这其中包括DevOps复杂性、分布式系统复杂性等。我们必须采用合适的分析设计方法、工具和流程,改善产品设计架构、自动化DevOps、建立高质量的领域模型等,从而最大限度获得微服务架构的好处,降低微服务架构带来的负面影响。
产品研发时首先调查市场需求背景,纵观国内,小微企业数量众多。其典型特点是数量多,单个企业业务量相对较少,没有专人负责系统管理和维护,整体IT水平不高,特别适合应用SAAS服务模式。而在近几年,随着云计算技术的发展,社会上出现大量商业业务创新,像电子支付、电子云仓和电子发票等商业基础设施走向商业应用。如何集成社会上出现的一些商业基础设施为小微企业所用?因此SaaS服务成为了众多小微企业唯一的选择。
进行问题分析时,需要明确客户群,面向数量多的小微企业,工贸公司、贸易公司和制造商,单个企业的业务不复杂,但是做一款产品同时满足多个企业是一个复杂问题。另外作为云产品,要保证产品在7×24小时内始终运行,在这个始终运行的产品上做升级和维护也是一个高风险的活动。
基于以上问题和背景,我们提出几个设计目标,如产品架构支持大规模并发用户需要;模型和架构支持持续、快速演进;通过产品的开发积累企业基础业务能力,为将来新产品的快速开发积累可用资源。
而基于设计目标,我们明确以下几个总体思路。
第一是重视设计,设计既是产品的未来,只有好的设计,我们的产品才能再客户业务成长的路上走得更远。第二是充分利用第三方技术,专注我们自己擅长的领域。第三是在时间和资源有限的情况下,分离关注点,简单实现,保障在将来有资源的情况下,系统能够演进。第四是采用DDD方法进行领域切分和解耦,微服务充分保障业务的内聚。最后是最为业务系统,领域模型是其核心和基因,是将来支持业务演进的基础,提高领域模型质量,模型设计适当超前。
SAAS产品研发专业强,涉及的技术栈和能力较多,前后端采用完全不同的技术栈,各自独立开发。此外,作为一款满足众多用户需求的产品,定制化是其基本能力,前后端的平台是产品的基础能力。与之相对应,研发组织切分为多个小团队,例如产品,UI/UE,前端、后端、测试、运维、业务运营。
研发团队切分为多个小组,各个小组之间相互协作。如何保障不同团队之间合作高效,完整规范和标准必不可少,执行研发全生命周期的规范,可以有效提供工作质量和协作效率。
微服务架构模式在带来好处的同时,也带来DevOps的复杂性,建立自动化运维过程是使用微服务架构的必要条件。依据公司的产品开发发布流程制定合适的分支方案、制品管理方案、持续集成方案、环境管理方案。
-
分支分为develop、test和release分支,将开发、测试和发布进行空间上隔离;
-
开发人员从develop分支下载最新版本,构建成功之后发布到Nexus,通过自动任务将Nexus上的snapshot包发布到“Auto Testing”环境,然后在该环境上执行自动集成测试;
-
自动测试成功之后,将构建的包发布到develop环境;
-
在develop环境中由开发人员完成人工确认和验证;
-
人工确认完成之后,驱动自动任务将develop中内容merge/rebase到test分支,测试人员通过手工执行jenkins任务完成release包发布到集成测试环境过程;
- 运维人员负责维护生产环境,生产环境支持灰度部署,降低新版本交付的风险。
采用微服务架构不仅仅采用一种新的技术方式,如果没有采用相应的分析设计的方法进行辅助,其带来的弊将大于利,我们会陷入从一个火坑跳入另外一个火坑的尴尬。需要从业务建模、系统建模、领域建模、物理建模几个层次进行分步设计,提高微服务设计质量,保障产品将来可以持续演进。
分析设计包括工具、方法和流程。制造和使用工具是人类社会区别其它动物的标志,采用合适的工具可以极大提高分析设计的效率和质量。分析设计工具采用EA,DB建模工具采用ERWin。方法是凝集业界的最佳实践,领域驱动设计方法是面向对象思想的回归和升华,正确掌握领域驱动设计的前提是对面向对象的设计技巧。DDD是对面向对象设计最重要的原则——软件结构反映问题的结构的落地。采用DDD分析方法对业务进行分析和设计,分析设计流程包括业务建模、系统建模、领域建模和物理模型。
对于复杂系统,系统外观是很难想象出来的,必须通过工程化方法分析得到的,也就是通过业务建模的方法分析得到系统外观。业务建模是把整个组织都作为一个研究对象,选取典型的业务场景,识别组织中包含的角色和系统,并把系统看成是黑盒子,分析组织里的角色和系统如何相互协作完成业务,对外输出业务价值。
业务建模之后得到系统的外观,然后通过系统建模分析系统里面到底有哪些组件组成或者模块组成的。切分模块的目的是分离关注点,降低系统复杂性。把系统拆成一个个模块,这些模块之间怎么相互协作,满足系统外观里面所要求的功能,这就是系统系列图。对复杂的系统,通过分析模块之间的协作,得到每个模块的外观。
业务世界外在纷繁复杂,其内在本质的东西相对稳定,领域建模的目的就是通过事物的纷繁的现象和外观洞悉事物本质。领域模型也是我们看待业务世界的一种方式,帮助企业在产品设计时理清业务中包含的概念以及概念之间的关系。领域模型是表达业务功能(表象)背后的业务本质的模型,领域模型属于知识级模型,具有更高的稳定性,支持在线系统业务变更。
物理模型是领域模型的关系表达,是面向物理表。把表建好,用转换的工具可以依据表生成代码,保障设计的模型不仅仅是纸上或挂在墙上的一个摆设,是一个能够真正落地驱动开发的东西。
基于SaaS产品实施方案,包括多项重要技术选择,比如租户模式,分层设计,应用架构,总体技术架构,模块里面的技术架构,以及在微服务架构下、分布式环境下产品的一致性方案。
什么叫租户模式?SaaS产品需要使用应用、虚机和DB三种资源资源。按照对虚机、应用和DB的使用方式分为不同的模式。虚机模式就是每个租户有独立的虚机,有独立的应用和独立的DB,租户资源不共享,租户之间隔离性好,但资源利用率低。租户独立DB模式每个租户共享虚机和应用,DB由每个租户专用,虚机和应用资源利用率高,但DB资源利用率低。
第三种模式是租户共享DB模式,虚机、应用和DB都为所有租户共享,资源利用率高,租户之间软隔离,隔离性差。
对于小微企业群体,租户数量大,载荷不均匀,对个性化需求要求不高,我们决定采用租户共享DB模式。
对于复杂系统,分层设计是解决复杂性问题的重要手段之一。采用DDD的方法按照业务的视角对系统进行分层设计。同层之间和上下层之间可以调用,严格控制循环调用,控制依赖的复杂性。
前后端采用不同的技术栈,前后端进行分离设计,各*独立的部门进行开发。后端分为应用服务层和领域层。其中应用服务层是利用领域知识提供的服务能力,提供业务功能,解决具体业务问题。领域层包括核心领域层、支持子域层和通用子域层,提供领域知识服务能力。
-
核心领域层 - 为客户核心业务提供服务;
-
支持子域层 - 支持业务某一方面的子域;
- 通用子域 - 用于整个系统的子域
从技术的视角,能力层(包括通用子域服务、支持子域服务和核心子域服务)各个微服务之间通过RPC方式进行调用。应用服务层通过RPC方式调用领域服务层。应用服务层通过REST方式对外发布服务,由前端NodeJS接口服务器进行调用。前端应用通过HTTP/HTTPS的方式访问NodeJS服务。
生成物理模型之后,依据物理模型和插件生成Repository层、领域层和持久层,模型不再是挂在墙上的摆设,通过模型驱动代码,让模型真正落地。采用知识绑定方式将贫血的对象与知识件绑定,贫血对象变为智能对象(Smart Object)。实际上这种方案是考虑自动代码生成在贫血和充血模型之间的折中。
不同于传统单体系统,可以通过XA事务解决分布式资源数据一致性问题。在分布式系统运行场景下,各个服务运行在不同的进程中,各个进程独立运行,维护业务一致性是一个复杂的问题。系统提供两种一致性机制,即TCC的强一致性和基于消息+TCC调用的最终一致性。两种一致性机制适应不同的场景。
在很多业务场景下,在客户请求之后,系统需要做一序列复杂操作。这些操作中,有些操作需要即时执行并响应;还有些操作实时性要求不高,可以在请求响应之后再交给系统处理。基于消息+TCC的最终一致性方式就是应用这种场景的一致性机制。通过消息的方式将系统解耦,进行异步操作,同时也起到削峰填谷的作用,平衡系统载荷。
相对传统软件包产品,云产品升级是一个高风险的活动,设计高质量的领域架构和灵活的领域模型是云产品从容应对业务变化的基础。在建立云产品研发体系时,构建包括核心业务服务能力、支持业务服务能力和通用业务服务能力等公司基础业务服务能力,能极大缩短后期产品研发周期,这些基础服务能力是公司快速业务创新的基础。