服务的拆分策略

微服务是一种架构风格:
微服务架构也是一种架构风格。它的实现视图由多个组件构成。它的组件是服务,连接器是使这些服务能够协作的通信协议(如HTTP REST RPC)。每个服务都有自己的逻辑视图架构。

模式:微服务架构:
将应用程序构建为松耦合、可独立部署的一组服务。

什么是服务:
服务是一个单一的、可独立部署的软件组件,它实现了一些有用的功能。列如 User Service服务。此服务具有API,为客户端提供对功能的访问。有两种类型操作:命令和查询。API又命令、查询和事件组成。命令如createUser()执行操作并更新数据。查询如getUserById()检索数据。

什么是松耦合:

  • 微服务架构的最核心的特性是服务之间的松耦合性。服务之间的交互采用API完成,这样做就封装了服务的实现细节。这允许服务在不影响客户端的情况下,对实现方式做出修改。小的、送耦合的服务更容易被理解、修改和测试。
  • 通过API来实现送耦合服务之间的协调调通,这样就避免了其他服务对数据库的直接访问和调用。服务自身的持久化数据就如同类的私有属性一样,是不对外的。保证数据的私有属性是实现送耦合的前提之一。但是服务之间不共享数据库,使得处理数据一致性和跨服务查询都变得更为复杂。

服务的大小并不重要:

  • 微服务这个术语的一个问题是会将关注点错误的聚焦在微上。它暗示服务应该非常小。实际上大小不是一个重要的考虑因素。

  • 更好的目标是将精心设计的服务定义为能够由小团队开发的服务,并且能够快速完成,与其他团队协作最少。理论上,团队可能只负责单一服务,因此服务绝不是微小的。另外如果因为其他服务的变更而不断地需要同步更新其他的服务,这表明服务没有实现松耦合。可能构建了一个分布式的单体。

为应用程序定义微服务架构:
如何定义一个微服务架构呢?和所有的软件件一样,设计微服务架构是根据业务需求来设计的,设计架构是一种艺术而并非是一种技术。
世界上并没有一个固定的流程可以遵循,然后指望这个流程输出一个合理的架构。我们只能遵循一个大概的方法,这是一个不断迭代和持续创新的过程。

  1. 定义系统操作(也就是用户的操作):
    在定义系统操作的时,首先我们需要识别系统操作。第一步创建由类组成的抽象领域模型。第二步确定系统操作,并根据领域模型描述每个系统操作行为。例如一个订单服务,我们可以抽象出它的一些领域模型,比如下单、查询订单,取消订单等,根据抽象出来的模型 我们可以确定该商城有以下两种类型的系统操作:

     - 命令型:创建、更新、删除的操作  		
     - 查询型:查询和读取的操作
    从根本上来说,这些操作都会对应到具体的HTTP REST或RPC消息端口上。
    系统定义后,下一步就是完成应用服务的识别。这并不是一个机械化的流程,相反,有多种拆分策略可供选择。每一种都是从一个侧面来解决问题,并且它们独有一些术语。但是殊途同归,这些策略的结果都是一个的:一个包含若干服务的架构,这样的架构是以业务为中心,而不是技术。
    

    根据业务能力进行服务拆分:
    创建微服务的策略之一就是采用业务能力进行服务拆分。业务能力是一个来自于业务架构建模的术语。通常是指产品设计的某个模块,这个产品可以做什么。

    1. 识别业务能力:
    		一个产品有哪些业务能力,是通过对产品的目标、结构和商业流程分析得来的。每一个业务能力都可以被认为是一个服务。业务能力规范包含多选元素、比如输入和输出、服务等级协议。
    2.从业务能力到服务
    	一旦确定了业务能力,就可以为每个能力或相关能力组定义服务。
    
  2. 根据子域进行服务拆分
    以领域驱动设计是构建复杂软件的方法论,这些软件通常都以面向对象和领域模型为核心。领域模型以解决具体问题的方式包含一个领域内的知识。它定义了当前领域相关团队的词汇表,DDD也称之为通用语言。领域模型会被紧密地映射到应用的设计和实现环节。在微服务架构的设计层面,DDD有两个特别重要的概念,子域和限界上下文。
    我们可以通过DDD方式定义子域,并把每个子域对应为每一个服务,这样就完成了微服务架构的设计工作。比如,外卖平台的子域大概包括:订单获取、订单管理、餐厅管理、配送员管理、支付、用户。

拆分的指导原则:
在应用微服务架构模式时,我们还可以采纳和使用面向对象设计的一些原则。面向对象设计的一些原则也可以用于指导微服务架构的设计工作。

  1. 单一职责原则:
    软件架构和设计的主要目标之一是确定每个软件元素的职责。单一职责原则如下:

    1. 改变一个类应该只有一个理由
    	类所承载的每一个职责都是对它进行修改的潜在原因。如果一个类承载了多个职责,并且互相之间的修改是独立的,那么这个类就会变得非常不稳定。遵照SRP原则,所定义的每一个类都应该只有一个职责,因此也就只有一个理由对它进行修改。
    	在设计微服务架构时也应该遵循SRP原则,设计的小的,内聚的、仅仅含有单一职责的服务。
    
    2. 闭包原则(CCP): 
    	在包中包含的所有类应该是对同类的变化的一个集合,也就是说,如果对包做出修改,需要调整的类应该都在这个包内。	
    	在微服务架构下采用CCP原则,这样就能根据同样原因进行变化的服务放在一个组件内。这样做可以控制服务的数量,当需求发生变化时,变更和部署也更加容易。理想情况下,一个变更只会影响一个团队和一个服务。CCP是解决分布式单体这种可怕的反模式的法宝。
    
    1. 拆分单体应用成为服务的难点:

      1. 网络延迟
        网络延迟是分布式系统中一直存在的问题,因为网络从来都不是100%的没有问题。对服务的特定分解会导致两个服务之间的大量的往返调用。有时,可以通过实施处理API在一次往返中获取多个对象,从而将延迟减少到可接受的数量。但是在其他情况下,解决方案是把多个相关的服务组合在一起,用编程语言的函数调用替换昂贵的进程间通信。

      2. 同步进程间通信导致可用性降低
        还有需要处理的问题是如何处理进程间通信而不降低系统的可用性。例如createOrder 操作最常见的方式是让OrderService使用REST同步调用其他服务。这样做的弊端是REST这样的协议会降低OrderServer的可用性。如果任何一个服务处于不可用状态,那么订单就无法创建了。这时候我们就可以使用异步的方式来解决该问题。

      3. 在服务之间维持数据一致性
        另一个挑战是如何在某些操作需要更新多个服务中的数据时,仍然维护服务之间的数据一致性。使用Saga来解决该问题。Saga是一系列使用消息协作的本地事务。Saga比传统的ACID事务更负责,但是它们在很多情况下都工作得很好。Saga的一个限制是它们最终是一致的。

      4. 获取一致的数据视图
        分解的另一个障碍是无法跨多个数据库获得真正一致的数据视图。在单体应用中,ACID事务的属性保证查询将返回数据库的一致视图。但是在微服务架构中,即使每个服务的数据库是一致,也无法获得全局一致的数据视图。在实践中这很少带来真正的问题。

      5. 上帝类阻碍了拆分
        分解的另一个障碍是存在所谓的上帝类。上帝类是整个应用程序中使用的全局类。

定义服务API:
定义每个服务的API:也就是服务的操作和事件。存在服务API操作有以下两个原因:
1.某些操作对应于系统操作。它们由外部客户端调用,也可能是其他服务调用
2.存在一些其他操作用以支持服务之间的协作。这些操作仅由其他服务调用

总结

  1. 架构决定了软件的各种非功能性因素,比如可维护性、可测试性、可部署性和可扩展性,它们会直接影响开发速度。

  2. 微服务架构是一种架构风格,它给应用程序带来了更高的可维护性、可测试性、可部署性、可扩展性

  3. 微服务中的服务是根据业务需求进行组织的,按照业务能力或者子域,而不是技术上的考量

  4. 有两种拆分模式:
    按业务能力拆分,起源于业务架构
    基于领域驱动设计的概念,通过子域进行拆分

  5. 可以通过应用DDD并为每个服务定义单独的领域模型来消除上帝类(即全局类),正是上帝类引起了阻碍分解的交织依赖项

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值