作者丨崔皓
策划丨孙淑娟
【51CTO.com原创稿件】业务的飞速发展以及变化多端的动态组合一直推着以 IaaS、PaaS 和 SaaS 形式表现的云计算不断发展,随之微服务的实施方案也需要与时俱进。
放眼业内,谷歌、沃尔玛和亚马逊等科技巨头都开始不同程度地使用微服务架构和方案,他们期待通过微服务提供的模块化方案作为业务流程再造的基石,适应更加灵活复杂的商业场景。
从单体架构到微服务架构
单体软件架构使用单一的方法和模型构建应用体系,虽然通过分成的方式将应用与应用之间进行隔离,并且在业务逻辑上面便于理解,同时具备开发周期可控的特点,但单体架构的可扩展性一直是大家诟病的缺点。
单体架构由于其自身特点对于扩展性有多种限制,例如资源可用较差、需要更长的部署周期、无法持续交付、技术栈单一无法发挥技术多样性带来的优势,同时架构中单个应用的故障会影响到整体软件。
企业期待采用模块化和动态组合的方法来解决以上问题,因为模块的动态组合对于灵活复杂的业务逻辑更具备业务推动力。
这正应了 Adrian Cockcroft,Battery Ventures,说的那句话:
“微服务是具备有限上下文、松散耦合、面向服务的架构。”
松耦合模块会根据应用程序的需求进行合理组合。每个服务可以通过不同的技术栈来实现,并且可以独立扩展,从而应对业务的调整。这就意味着服务之间是需要协同工作的,一个应用的输出会变成另一个应用的输入,服务之间也可以通过 API 进行有效通讯。同时,由于微服务的隔离机制,导致每个服务都可以进行有效的安全监控。例如使用 Python 开发的服务就不需要其他技术能力的支持,这种情况在微服务开发中普遍存在。
虽然服务内部的技术各有不同,到协同工作时,服务以及对外界的接口和传输方式却可以统一规定。例如使用 (REST) API 的方式进行服务之间的沟通,使用 HTTP 协议传输数据,利用统一资源标识符 (URI) 与前端系统(Android/iOS、HTML5/JavaScript)进行沟通。
举一个例子来说明单体服务和微服务的区别。
单体架构类似于希腊的石头雕像,而微服务类似乐高积木。石雕的某个部分损坏,必须报废整个雕像,对其进行重造。而乐高积木只需要更换部分组件即可。
显而易见微服务在架构复杂系统时,是具备优势的,但是在落地过程中需要平衡速度和安全性。众所周知微服务在 DevOps 领域以及持续开发持续集成(CD/CI)方面可以提高应用开发和交付的速度,特别适用于复杂业务场景,并且提升交付速度。
但是由于微服务的服务独立和分散的特点,我们还需要关注每个服务的安全性问题,因此在微服务架构的设计和实施方案中需要考虑通过统一的服务编写或者实施标准来规避安全风险,这里建议创建“central key deliverable”(中心关键交付原则 / 标准),所有服务都围绕这个标准进行设计,避免各个服务各自为政。
微服务实施模型
第 1 阶段:专注于敏捷性和响应性
在线流媒体服务 Netflix 以提供点播服务而著称,它为用户提供了优质的 USP 体验。微服务的架构使得交付周期大幅缩短,开发频率提高,同时还提供持续的服务交付。
针对应用的特性而言,每个应用所需要的资源量并不是相等的。有些应用可能比其他应用被使用的频率更高,因此需要更多的资源作为支撑。以核心业务能力作为架构的中心,其他服务作为核心能力的扩充。比如视频播放就是核心业务,会员点播、订阅、积分等等就需要围绕这个核心业务展开,这些围绕核心业务的服务可以以微服务的形式存在,但需要与核心业务建立良好的调用接口和通讯模式。
因此可以讲核心服务与企业服务从以下两个层面进行定义:
功能层面的扩展:围绕核心服务的其他服务作为应用功能的扩展,对于 Netflix 而言核心服务无疑是视频的播放,而其他的周边服务会根据用户需求的增加或者改变进行调整。这种根据业务和用户需求扩展的服务就需要能够自由扩展,同时也不会影响核心服务,这里就需要使用到微服务的敏捷性特征,定义好扩展服务与核心服务的接口和协议以后,就可以针对用户需求对服务进行扩展。
资源能力的扩展:如果说功能层面的扩展和业务挂钩,资源能力的扩展就是和流量挂钩。由于 Netflix 本质还是资源 / 服务的提供者,而消费资源 / 服务的用户的数量并不是一定的,如何做到资源的伸缩是 Netflix 需要考虑的问题。在真实业务场景中,用户的访问量或者说网站的流量是波动的,那么 Netflix 网站提供的资源也应该随着用户的访问量的变化而及时调整。在微服务架构中就可以灵活地调整这种资源的分配,Netflix 就是针对 5 个用户使用资源作为步长进行资源扩展或者收缩,实际上在很多计算机技术中也会利用类似的思路解决资源的不确定性。例如 MySQL 中的 VARCHAR 类型也是通过变长的方式扩展字符的存储空间的。
第 2 阶段:管理安全性和源代码成熟度统一
尽管采用微服务架构每个服务都可以使用不同技术栈完成不同的业务功能,但毕竟所有的服务都是为了完成一个商业目的,同时存在于一个系统中。因此在微服务的实施过程中注重每个单独服务的安全性管理,以货币交易系统为例,如果采用微服务的架构,那么其中的转账服务、工资发放服务、零售交易服务都需要遵从相同的安全级别。
这个在微服务实施过程中尤为重要,也是在考验微服务架构安全管理的能力。换句话说就是针对微服务定义安全准则包括数据安全性、通讯安全性、访问安全性。甚至提供通用的微服务包装这些安全规则,其他的服务只需要调用对应的标准服务或者组件即可,这样即便是使用不同技术栈的服务也能遵循同样的安全标准。
除了安全标准,微服务还需要对代码成熟度进行管理,需要标准化每个服务源代码的成熟度级别,以在服务提供阶段提供特定目标和解决方案。但是如果针对每个服务源代码去定义成熟级别,显然无法做到架构层面的统一,而且在微服务的开发过程中会有多个团队共同参与,代码有可能会被多个继任团队维护,因此需要从整个系统的高度去定义代码成熟度的级别。
不这样做,服务内部不仅不能应对复杂的业务变化,也无法与整体架构统一做到目标(速度 / 安全性)与系统的可扩展。因此,单个服务的源代码变更需要与系统整体源代码的成熟度保持一致,从而降低两者缺乏同步的长期风险。简单来说就是单个微服务以及整体架构的代码成熟度需要保持一致。
众所周知一个软件的非功能性需求包括:高性能、可用性、扩展性、伸缩性、安全性。每个维度都可以定义成熟度的指标和级别。例如软件安全的成熟度模型中就会从监管、构造、确认、部署等四个方面进行定义。每个类别又会分三个等级来定义成熟度的级别,这里不展开说明。
第 3 阶段:确保解决方案和系统运营的可扩展性
系统实施之后的返工成本非常高,因此系统设计初期就需要考虑业务扩展以及访问存储量的增加,总的来说是要未雨绸缪。特别是在业务场景复杂、商业环境多变的当下,应用架构的扩展和伸缩需要和业务发展以及收入保持匹配,避免两者出现不一致的情况。例如业务量增长了,系统无法承载高访问量,又或者业务拓展以后在原有核心功能上增加了其他功能,而系统架构对于功能扩展反映缓慢,又或许无法扩展。
其中需要注意的是,系统的解决方案需要符合业务的扩展、向外能够兼容第三方软件、随着业务增加重新部署周期保持在平均水平、系统的访问量波动和运营成本保持一致。
另一个需要注意的是系统功能层面需要有长远考虑,降低系统的复杂性水平,避免后续功能的引入对系统的影响。例如在系统设计初期可以根据实际业务进行接口设计,而针对当时的情况进行业务实现,这样可以应对业务的变化。
例如创建一个中间平台,为卡车服务和客户之间充当中介者的角色,那么就要考虑到接入不同的卡车服务包括:个人卡车用户、集体卡车用户、以及平台。同时也要考虑结算服务,针对不同的结算方式(微信、支付宝、网银),又或者针对同一种支付方式的不同支付实体(例如:网银包括:工商银行、建设银行、招商银行等)建立对应的接口,所有的服务是面向接口进行编程,一旦实现的对象例如支付实体从微信切换成了支付宝,又例如网银实体从工商银行切换成了招商银行,只需要用新的服务实现替换就可以了,服务之间的接口并不需要进行调整。而接口的定义恰恰是在架构设计阶段是可以预见的。
第 4 阶段:保证单个服务的独立性和完整性 - 服务即解决方案
整个微服务架构就是多个独立服务组成的,每个服务就是一个独立的解决方案,单个服务尽量不对其他服务进行依赖,如果是依赖也是对接口进行依赖。这样的设计就好像乐高积木一样,每个服务各司其职,也很容易被替换和扩展。
针对每个服务定义规范的功能描述和输入输出参数,以及消息传送格式,并且将这些信息在系统内部公开,让其他服务知道该服务所完成的功能和服务边界是什么。这种方式让服务与服务之间能够做到无缝对接,也避免了重复造轮子的尴尬,同时也为数据中台、服务中台打下了基础。
在 Walmart Labs 的案例中,系统架构每月进行多达 30,000 次更新,而这些更新是由 3000 名工程师使用 OneOps 平台完成的。由于将服务的云化,提高了开发效率降低了开发新业务的难度,提升了组织在不同领域的竞争力。
也就是说公司面对复杂环境时可以利用哪些不变的服务组件(颗粒度足够小)以及公司对市场以及业务的理解,通过组合、集成、扩展的方式快速高效地搭建新的应用程序,从而快速适合新的业务模式,服务客户占领市场。
第 5 阶段:善用流程、 工具和组织结构
公司需要明白,想让微服务成功落地就需要对系统构建过程进行改革,不同于传统单体应用的层级开发模型。开发者工作在不同的层级上,前端、后端、H5 ,甚至在后端中还可以划分为面向数据库以及面向业务的开发。这种方式在微服务环境中已经不适用,必须要开发人员知道自己就是微服务的主人,你开发的微服务就是代表你的产品,它会被系统中其他的服务消费,也就是说其他服务就是你的客户。所以,你必须成为唯一对该服务负责的人,只要和这个服务相关的一切都需要关注,这就迫使开发人员成为全栈工程师,对人、对组织、对开发流程都是较高的要求。
微服务的开发者需要把服务当作产品一样管理,包括设计、编码、UI 开发、同时还要保证质量交付和以及运维过程中的故障排除和调试升级。
看上去开发者的责任变大了,不过有一些 DevOps 工具通过持续集成和交付的方式协助微服务的开发,从而确保单点故障 (SPOF) 不会影响其他服务。同时也引入了容器化的部署方式,Docker 的部署方式就是很明显的例子。Docker 的部署只针对单个服务的范围,提高了标准化以及利用容器映像 (CI Continued Integration 持续集成) 的效率。比起传统方式的整体发布来说,无论对发布成本和试错成本来说,容器化的部署工具都是性价比最高的选择。
第 6 阶段:整体系统实施策略
微服务架构是近几年随着业务发展兴起的,站在整体系统的角度如何落地微服务架构一直是架构师面临的问题。新的系统可以完全重新开始,但是对于遗留系统而言要实施微服务架构不是一件容易的事情。
这里提供了三种策略给大家参考,如图所示:
第一种 Cream Scoop Strategy 冰淇淋勺策略:是 Martin Flower 提出的一种策略,也被称为扼杀者方法。可以想象有一大桶冰淇淋,这桶冰淇淋就代表现有的架构,可以用勺子从桶中挖出你们想要的冰淇淋,这个挖出的部分就是要做拆分的服务。最终可以将大桶冰淇淋挖出一个个独立的服务,这里服务包含不同的业务逻辑。这种方式是逐渐修改原有系统,并且逐步对服务进行拆分试错然后过度到单独的资源上运行。每次拆分对系统的影响较小,但是整个系统的拆分和重构需要较长时间。
第二种 乐高法策略(搭积木),把原有的系统想象成一大块乐高积木,我们只需要往上面添加小的乐高积木模块就行了,添加的小模块就是一个个微服务。这样一来就不用对老产品进行调整,新的功能通过微服务的方式实现并且集成到老的产品中。不过需要通过一种能够让微服务与老产品联系的方法,这里会使用到接口编程以及适配器模式。
第三种是 nuclear 策略,和策略的名字一样我们需要对老旧系统推到重来,重新打造微服务架构,说起来容易这里需要花费大量分析和重构的时间,这个周期比较长,成本也是较高的。
微服务架构实施策略
第 7 阶段:调整姿态直面转型
在微服务架构实施过程中,领导方式和公司文化都起着举足轻重的作用,无论在何种情况下这两点都是复杂、模糊且多变的因素。也就是没有很好的建议和思路,只有见招拆招不断适应业务的变化调整组织能力和领导方向。不过有一点是可以肯定的,企业需要不断观察和分析市场的变化倾听客户的声音,将变革的频率与市场的波动同步,打造自我学习不断适应的企业文化。领导方式需要在企业文化的基础上,不断对外来需求进行评估,从而开阔视野,简化最终结果不断迭代,因为谁也不能保证开发出完美的系统和产品。唯有适应市场的变化,不断提升自身能力,持续打磨系统,才能立于不败之地。以终为始,打造领导力,调整组织结构,创建公司文化,让利益相关者信任并参与进来,形成公司的核心竞争力。
总结
本文从业务发展说起,为了适应复杂多变的业务场景,系统从单体架构进化到了微服务架构。独立服务、功能可扩展性以及资源的伸缩性让微服务架构在纷繁复杂的商业环境中占领了一席之地。
但也正因为这些特性增加了微服务落地的复杂度,本文通过 7 个阶段模型帮助企业落地微服务架构。包括:
- 专注敏捷性和响应性:功能和资源层面的扩展;
- 安全性和源代码成熟度:创建安全和成熟度标准;
- 解决方案和系统运营的可扩展性;
- 服务的独立性和完整性;
- 善用流程、工具和组织结构;
- 整体系统实施策略;
- 调整姿态直面转型。
作者介绍
崔皓,51CTO 社区编辑,资深架构师,拥有 18 年的软件开发和架构经验,10 年分布式架构经验。曾任惠普技术专家。乐于分享,撰写了很多热门技术文章,阅读量超过 60 万。《分布式架构原理与实践》作者。
【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】