微服务认知学习

微服务是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

— James Lewis and Martin Fowler

这是James和Martin2014年在《微服务》一文中提到的对于“微服务”的定义。相对于单体架构和SOA,它的主要特点是组件化、松耦合、自治、去中心化,体现在以下几个方面:

  • 一组小的服务

服务粒度要小,而每个服务是针对一个单一职责的业务能力的封装,专注做好一件事情。

  • 独立部署运行和扩展

每个服务能够独立被部署并运行在一个进程内。这种运行和部署方式能够赋予系统灵活的代码组织方式和发布节奏,使得快速交付和应对变化成为可能。

  • 独立开发和演化

技术选型灵活,不受遗留系统技术约束。合适的业务问题选择合适的技术可以独立演化。服务与服务之间采取与语言无关的API进行集成。相对于单体架构,微服务架构是更面向业务创新的一种架构模式。

  • 独立团队和自治

团队对服务的整个生命周期负责,工作在独立的上下文中,自己决策自己治理,而不需要统一的指挥中心。团队和团队之间通过松散的社区部落进行衔接。

我们可以看到整个微服务的思想就如我们现在面对信息爆炸、知识爆炸是一样的:通过解耦我们所做的事情,分而治之以减少不必要的损耗,使得整个复杂的系统和组织能够快速的应对变化。

https://mp.weixin.qq.com/s/0NH-YHmC50eDTrR6daZIAA  

服务拆分与架构演进|洞见

然而谈到微服务,我们不能忽视的一点是:微服务仍然是典型的分布式系统,它必然有分布式系统固有的问题:诸如怎么部署,出错怎么办,怎么保证数据的最后一致性;与此同时,还有服务要多微?业务变化后服务如何调整?服务规模化后怎么办?如何避免一个服务改动导致的多个级联服务的失败?如何进行测试等等问题。

  • 如何拆?即如何正确理解业务,将单体结构拆分为服务化架构?

  • 拆完后业务变了增加了怎么办?即在业务需求不断发展变化的前提下,如何持续快速地演进? 

  • 如何安全地持续地拆?即如何在不影响当下系统运行状态的前提下,持续安全地演进?

  • 如何保证拆对了?

  • 拆完了怎么保证不被破坏?

问题1:如何将单体结构拆分为服务化架构? 

就如庖丁解牛一样,拆分需要摸清内部的构造脉络,在筋骨缝隙处下刀。那么微服务架构中,我们认为服务是业务能力的代表,需要围绕业务进行组织。拆分的关键在于正确理解业务,识别单体内部的业务领域及其边界,并按边界进行拆分。

1. 识别业务领域及边界。

首先需要将客户、体验设计师、业务分析师、技术人员集结在一起对业务需求进行沟通,随后对其进行领域划分,确定限界上下文(Boundary Context),也称战略建模。

以下我们经常使用的方法和参考的红蓝宝书:

  • Inception-> User Journey | Scenarios。用于梳理业务流程,由粗粒度到细粒度逐一场景分析。

  • 四色建模。用于提取核心概念、关键数据项和业务约束。 领域驱动设计-战略设计,用于划分领域及边界、进行技术验证。 

  • Eventstorming。用于提取领域中的业务事件,便于正确建模。

 

Inception与DDD战略设计的对比:

一个业务领域或子域是一个企业中的业务范围以及在其中进行的活动,核心子域指业务成功的主要促成因素,是企业的核心竞争力;通用子域不是核心,但被整个业务系统所使用;支撑子域不是核心,不被整个系统使用,该能力可从外部购买。一个业务领域和子域可以包括多个业务能力,一个业务能力对应一个服务。领域的边界即限界上下文,也是服务的边界,它封装了一系列的领域模型

 

领域划分的原则

 

在划分的过程中,经常纠结的一个问题是:这个模型(概念或数据)看起来放这个领域合适,放另一个也合适,如何抉择呢?

  • 第一,依据该模型与边界内其他模型或角色关系的紧密程度。比如,是否当该模型变化时,其他模型也需要进行变化;该数据是否通常由当前上下文中的角色在当前活动范围内使用。

  • 第二,服务边界内的业务能力职责应单一,不是完成同一业务能力的模型不放在同一个上下文中。

  • 第三,划分的子域和服务需满足正交原则。领域名字代表的自然语言上下文保持互相独立。

  • 第四,读写分离的原则。例如报表需有单独报表子域。核心子域的划分更多基于来自业务价值的产生方,而非不产生价值的报表系统。

  • 第五,模型在很多业务操作中同时被修改和更新。

  • 第六,组织中业务部分的划分也是一种参考,一个业务部门的存在往往有其独特的业务价值。

简单打个比方,同一个领域上下文中的模型要保持近亲关系,五福以内,同一血统(业务)。

 

领域划分的误区和建议 

 

  • 业务能力还是计算能力?一些识别为通用的领域其实只是通用的计算能力而不是业务能力,对于它们,只需采用通用库的方式进行封装,而无需使用服务的方式。如我们系统的模板服务,是构建通用的模板服务,服务于整个平台的服务;还是每个服务拥有独立的模板模块?

  • 尽早识别剥离通用领域。如身份认证与鉴权领域,是企业系统中最复杂、有相对多变的领域,需要及早隔离它对核心业务的干扰。

  • 时刻促成技术人员与客户、业务人员的对话。业务领域的划分离不开对业务意图的真正理解。而需求人员和体验设计师对于User Journey的使用更熟悉,而技术人员、架构师对领域驱动设计、Eventstorming更熟悉。不管哪种方法都要求跨角色的群体协同工作,即客户人员、业务分析师、体验设计师与技术人员、架构师。

    而现实的情况中,User Journey更多的在Inception,在需求阶段进行,而领域驱动设计、Eventstorming更多的在开发设计阶段被使用,故而需求阶段经常缺失技术人员,而开发设计阶段经常缺失客户、业务人员的参与。

    另一个常见的现象是,Inception的参与人员和真正的开发团队有可能不是同一个群体,那么Inception中的业务沟通往往以UI的方式作为传递,因此在开发中经常只能通过UI设计来理解业务的真正意图。 所以要想将正确的理解业务,做对软件,需要时刻促成技术人员与客户、业务人员的对话。

识别了被拆对象的结构和边界,下一步需要决定拆分的策略和拆分的步骤

 

问题2:拆分后业务变了增加了怎么办?

 

 

随着客户业务的变化,我们的服务也在持续的增加,而其中碰到了一个特大的服务。服务的大小如何衡量呢?该服务生产代码7万行+,测试代码14万行+,测试运行时间2个小时。团队中7个stream每天50%工作需要对这个服务进行更改,使得团队间的依赖非常严重,独立功能无法单独快速前行,交付速度及质量都受到了影响。 

我们的总结: 

客户的业务是在变化的,我们对业务的认知也是逐渐的过程,所以Martin Fowler在他的文章中提出,系统的初期建议以单体结构开始,随业务发展决定其是否被拆分或合并。那么这也意味着这样构建的服务在它的生命周期中必然会持续被拆分或合并。那么为了实现这样一个目标,使系统拥有快速的响应力,也要求这样的拆分必然是高效的低成本的。

因此,服务的设计需要满足如下的原则: 

  • 服务要有明确的业务边界,以单体开始并不意味着没有边界。服务要有边界,即使以单体开始也要定义单体时期的边界。我们系统中有一个名为“Monkey”的服务,是在中国虎年启动的,由此它并不是一个业务概念。当这个服务的名字为MonkeyAPI时,可以想象5年来它变成了什么?

    几乎所有和这个产品相关的功能都放入了这个服务中。脱离平台来看这一个产品的系统,其实它只是做了前后端分离而已。这个例子告诉我们,没有边界就会导致大杂烩,之后对其进行整理和重造的代价很大,可能需要花费“几代人”的努力。

  • 服务要有明确清晰的契约设计,即对外提供的业务能力。

  • 服务内部要保持高度模块化,才能够容易的被拆分。

  • 可测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值