微服务架构

软件架构

概述

软件架构对需求的影响

  • 对功能性需求的影响不大

    • 由user case和user story体现
  • 对非功能性需求影响较大

    • 包括可维护性、可测试性、可扩展性、可部署性

软件扩展的方式

  • 克隆实例。例子就是服务的弹性扩容。
  • 分解功能,每个功能单独实例。例子就是单体转为微服务。
  • 数据分区,在分区上克隆实例。例子就是分库然后各自部署微服务。

视图分类及架构风格

  • 应用程序通常使用多种架构风格的组合

  • 架构风格限定了部分视图中可以选择的元素和关系,比如微服务架构限定了实现视图是多个jar包,然后进而限定了进程视图是一定会有跨进程通信,部署视图会部署多个网络端口。

  • 架构风格

    • 分层架构风格

      • 可以应用于所有的4个视图
    • 六边形架构风格

      • 应用于逻辑视图
    • 单体架构风格

      • 应用于实现视图
    • 微服务架构风格

      • 应用于实现视图
  • 视图

    • 逻辑视图——元素是包和类,考虑设计模式、领域分解等关系
    • 实现视图——元素是jar和可执行文件,考虑依赖关系
    • 部署视图——元素是机器和进程,考虑网络关系
    • 进程视图——元素是进程,考虑进程间通信

业务组织逻辑

  • 面向过程的事务脚本模式

    • 特征是实现行为的类与存储状态的类是分开的
    • 设计风格高度面向过程,仅使用面向对象语言的少量功能
  • 面向对象的领域建模模式

    • 特征是类具有状态和行为,且状态是私有的,只能通过方法间接访问

    • 设计方法

      • 传统面向对象设计

        • 通过对象直接引用

        • 领域模型由一组类组织成包

        • 缺少明确的业务边界

          • 比如order和库存是两个对象,可以通过调用createorder更新库存,也可以直接改库存对象
      • 领域驱动设计

        • 通过id引用

        • 引入聚合这一核心逻辑概念

          • 聚合由根实体和一些其他实体构成

            • 比如由order作为聚合根,orderItem、paymentInfo等一起构成order聚合
          • 聚合通常从数据库整体加载,整体更新

          • 聚合对外暴露的只有聚合根

          • 聚合有明确的业务规则,更新对象必须满足规则

            • 比如order有最小金额
          • 聚合代表了一致的边界

            • 比如每次更改库存只能在聚合根上通过createOrder来改,然后需要锁定整个聚合
    • 领域建模适合做CUD命令,因为这些命令通常是针对单个实例的。而select命令通常会针对满足要求的多个实例,所以为了提升性能,实现时会绕过领域模型,直接访问数据库。比如查找满足要求的实例个数。

微服务

微服务区别于单体

  • 优点

    • 易于并行开发
    • 故障隔离
    • 代码复杂度降低
    • 测试的范围可以更加聚焦
  • 缺点

    • 服务间的数据库很难做事务和联合处理,数据一致性差

    • 不适合大量修改,接口需要向后兼容

    • 增加大量网络延迟

      • 可以通过容器部署时的亲和性来解决这个问题

微服务的拆分

  • 服务拆分的原则

    • 大小不重要,微服务不一定要小
    • 重要的是每个微服务能够由一个小团队开发,然后多个微服务能够并行开发
    • 微服务间一定要解耦,不能由一个的变更导致另一个的变更,否则就成了分布式单体程序
    • 过程一致性要求高的数据,需要划分到一个服务中
  • 操作

    • 两种划分方式

      • DDD跟微服务天生一对,可以每个子领域就是一个微服务
      • 也可以按业务能力进行分解,因为业务实现可能经常变化,但是业务能力通常趋于稳定
    • 类拆分的原则

      • 单一职责原则

        • 定义类的职责时,应该遵循单一职责原则,只有先定义好类,才能考虑类的修改
      • 闭包原则

        • 如果两个类的修改必须耦合,那就放一个包
        • 如果要对一个包做修改,则所有要修改的类都应该位于这个包内
    • 解决划分的阻碍

      • 数据一致性问题

        • 无法解决,只能保证数据的最终一致性
        • 哪怕微服务不分库都解决不了数据一致性的问题,因为没有事务。所以微服务还是要分库,尽量提高职责隔离,提升数据库性能。避免数据库瓶颈也是微服务的一个优点。
        • 如果单纯保证最终一致性不够,那就要考虑划分时分到两个微服务是否有问题。
      • 上帝类

        • 像Order这种类,在派送、厨房等很多领域都需要用到,合适的做法是让每个子域定义自己需要用到的order,然后通过一个id来进行关联。

进程间通信

  • 交互方式

    • 分类依据一对一、一对多,同步、异步。共两个维度4个选项进行

      • 请求响应
      • 异步请求响应
      • 单向通知
      • 发布订阅
    • 虽然交互方式和底层机制一般是选择相同的,但交互方式跟底层消息机制也没有绝对绑定,比如同步交互的底层可以用异步消息队列实现

    • 异步交互可以提高系统的可用性,因为同步交互的可用性是所有组件可用性相乘,而异步是取max。但是我们一般不是很关心可用性,更加关心的是系统的简单性

  • 底层消息机制

    • 同步调用,典型如restful

    • 异步消息队列

      • 消息去重

        • 程序幂等处理
        • 通过唯一性id判断
      • 消息顺序

        • 通过partition控制
      • 消息防丢失

        • 通过本地事务表,使用数据库的能力实现
  • 消息格式

    • 需要考虑跨语言兼容性
  • api

    • 需要考虑向后兼容
  • 服务发现

    • 发现模式

      • 服务端定期通过心跳上报可用状况
      • 客户端轮训所有服务,自己发现可用的服务
    • 功能实现所在层次

      • 应用层

        • 好处是可以处理多平台部署的问题
        • 坏处是需要框架支持
      • 平台层如k8s

        • 好处是免应用层管理
        • 坏处是跟平台绑定

事务管理

  • 分布式事务

    • 实现方式

      • 同步的本地事务表
      • 异步的saga
    • 具有的特性

      • 原子性
      • 最终一致性
      • 持久性
    • 需要解决的问题

      • 不具备隔离性

        • 根据业务特性,引入特定状态,作为语义锁

          • 比如order的pending状态
        • 根据业务本身幂等性进行处理

        • 允许不重要数据丢失或错误展示

监控

  • 功能点

    • 健康检查
    • 日志汇聚
    • 断路器
    • 降级
    • 调用链
    • 审计日志
    • 指标收集
  • 实现方式

    • 在微服务框架中实现

    • 在部署框架中实现

      • 只能实现部分功能,比如k8s可以实现服务发现,负载均衡等功能
      • 好处是可以不用跟微服务框架绑定

单体拆分为微服务

  • 难点

    • 可能需要重新拆分表结构,涉及到数据的迁移

      • 不停服的话则需要考虑引入全新的表,异步导数据的同时,新增数据使用双写的方式
    • 分库和拆分服务都会影响数据库事务,需要改成分布式事务,需要关注数据的一致性、事务的隔离性。

      • 服务间调用使用本地事务表
      • 分析业务本身的幂等特点
      • 引入语义锁
    • 需要考虑模型变更

      • 使用反腐层
  • 最佳实践

    • 1、把单体切换到微服务框架下,作为一个单独的微服务
    • 2、对于新增的完全独立的功能,作为单独的微服务实现
    • 3、识别数据库各表对应的功能有没有在事务中,是否可以拆分事务,以事务作为服务拆分的重要依据
    • 4、如果有大块功能不需要拆表和拆事务,则可以考虑把这块功能单独挪出来作为服务

高级模式

  • event sourcing模式

    • 领域事件

      • 是指聚合发生的事情,通常代表领域发生的变化
    • 与传统应用程序的区别

      • 不再通过接受命令方法的调用来更新聚合中的字段,而是通过响应一个事件来处理
      • 保留过程中的所有事件
      • 启动时,加载最原始的状态以及所有事件,计算得到当前状态,当然,也可以保存过程中的状态快照,加速启动过程
    • 优点

      • 保留所有的过程
    • 缺点

      • 对消息通道的可靠性要求高
      • 因为不保存最终状态,不支持直接查询满足某个条件的所有实例这种查询
      • 对业务逻辑的更改不友好,因为每次更改都要考虑所有历史事件是否有兼容性问题。
  • cqrs模式

    • 核心是职责隔离

    • 隔离方式

      • 单独抽取用于查询的服务

        • 服务可以通过响应事件的方式,实时刚新数据
      • 单独部署用于查询的数据库

        • 用于查询的数据库可以进行单独的表结构设计,无需保持和用于响应命令的数据库相同
        • 可以生成实时的状态视图,解决eventsourcing中不能复杂查询的问题
        • 查询数据库可以使用不同的架构,比如OLAP数据库
    • 缺点

      • 架构更加复杂
      • 数据具有滞后性
  • api gateway模式

    • 最佳实践

      • 分层

        • 公共层

          • 身份验证
          • 访问授权
          • 缓存
          • 日志
          • 限流
        • api层

          • 谁来维护

            • 不同端侧拥有各自的api转发控制,各自维护
            • 只有一个公共的api转发模块,由api gateway团队维护。
          • 和微服务数据模型解耦

            • 微服务返回全量数据,在api层由客户端定制数据聚合和筛选逻辑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值