微服务 Design Pattern

个人对微服务的感性理解

感觉 DP 的出现、兴盛还是在单体应用时代,为了更好地解耦模块。那么到了微服务时代,单个服务已经实现高内聚了,服务间的解耦又通常会是一种什么样的模式?

个人认为,DP 是对于常见的一些 OOP 技法的总结和梳理,粗糙地说,一切 DP都可以用,类、继承、接口等方式来模拟,不存在语言级别的特性。以上一名是废话,明明这个过程应该是倒过来的。

想当然的,在微服务模式下,是否在微服务中,也会被抽象出一些通行的 Pattern?而这一抽象的主体思想,也是解耦,那 DP 和微服务的常见模式之间是否存在可类比性?

  1. 网关 vs Facade
    • DP 中 Facade,将一堆操作,封装到 Facade 中,对外暴露一个较为简单的接口
  2. 代理 vs Proxy
  3. Adapter
    • DP 中 Adapter 用户协调多继承导致的接口不一致性,主要用于解决接口一致性问题
  4. Decorator vs sidebar 的 service-mesh
  5. Single vs 注册中心、服务发现
  6. 策略 vs 注册中心、服务发现

微服务细节

什么是微服务

其实是没什么明确的定义的,只是一种开始流行的服务端架构范式,以下引用 Martin Flower:

就目前而言,对于微服务业界并没有一个统一的、标准的定义(While there is no precise definition of this architectural style ) 。但通在其常而言,微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分成一组小的服务,每个服务运行独立的自己的进程中,服务之间互相协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API ) 。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务。可以使用不同的语言来编写服务,也可以使用不同的数据存储。

要点

  1. 服务小;但实际上粒度的问题很难有定论,还是要具体场合具体分析
  2. 独立进程
  3. 轻量级通信;TCP/HTTP 来实现 RPC,而不是 SOAP 之类的
  4. 基于业务的能力;架构是为业务服务的,DDD
  5. 独立部署;Devops 配合流行的原因
  6. 无集中式管理;没有集中点,不会由于任何一个单点故障,影响服务

康威定律

Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. - Melvin Conway(1967)

设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构

Conway

粒度划分

一个服务的逻辑粒度正好能够被一个单独的团队处理,这是一个合适的边界

开发运维关系

Devops 流程

微服务监控

  1. 端用户体验监控:性能、返回码、城市等(umeng)
  2. 业务监控:核心指标(订单量、注册用户数、支付成功率等)
  3. 应用监控:技术指标(DB 的 QPS、使用率等,JVM 的 GC)
  4. 系统监控:主机层指标,Docker 指标
  5. 基础设施监控:网络流量、连接数等

微服务的划分

其实并没有一个明确的划分黄金法则,多是各有各的道理,但我觉得,关注点应该在,有哪些要素是你用作划分的考量,这些要素的权重如何?

  1. 按业务线划分
    • 商城
    • 生鲜
  2. 按功能划分
    • 消息服务
    • 缓存服务
  3. 拆分后维护成本要低于拆分前
    • 拆分短期肯定会增加复杂度,长期是否可以更内聚?
  4. 拆分能够提高系统的扩展性
    • 其实和 3 类似,还是对高内聚、低耦合的新解释
  5. 考虑发布频率的拆分
    • 也可以认为是考虑服务稳定性的划分
    • 个人来说,引申到,基于访问量的划分(和6 有点类似)
  6. 基于性能的划分
    • 对于热点服务、热点功能拆分处理(这又跟 JVM Hotspot 类似了)
  7. 基于人员组织规模的划分
    • 3人就不要拆5 个服务了
    • 一个服务 3 个人,比较合适

      个人认为的权重,大概正好是倒着来

微服务调用的方式

RPC

最常见,通常来说,使用上最便利。但需要注意契约(接口)的向后兼容性,这一点上 Protobuf+gRPC 做的相对较好

事件驱动 Event-Driven

不使用 RPC,而是使用消息,将对协作者(依赖服务)的调用通过消息通知的方式传递出去。好处是:

  • 时间解耦
  • 容量解耦
  • 接口解耦
  • 发送方式解耦

已经逐步成为当前微服务设计中的主流远程调用方案。当然对于强耦合的服务间调用,RPC 也还是很合适的。

事件溯源 Event Sourcing

具有颠覆性质的的设计,把系统中所有数据以事件(Event)的方式记录,并持久化为 Event Store。是由 DDD 提出来的,跟事件驱动是两个范畴的东西。但确实在表现上有接近,Event Sourcing 更多是系统设计和实现上的考量。

在 Event Sourcing 中 Event 是一等公民,其余一切动作全部基于 Event 来实现。数据库并不是必须的,或者说,数据库中持久化的东西,是由某个 Service 用 EventStream 来输入的。最大的优势是,历史可追溯。

弱点:不利于查询,直接对 Event Stream 进行读操作只能作 Demo,通常需要用 Event Stream 构建另外的异构索引用于读

暂时讨论较多,还没有得到业界的广泛使用。本质行为上,和区块链有点像。

微服务的前置条件:

Phil Calçado总结了,如果你的团队要实施微服务,要满足以下的先决条件。

  • 快速配置:具备在短时间内配置好一台服务器的能力;
  • 基本的监控:生产环境中,很多轻度耦合的服务在一起协作容易出现问题,而这些问题在测试环境中难以被发现,所以我们需要一个有效的监控机制来快速地检测这些问题;
  • 快速部署:因为需要管理的服务太多,所以需要尽快地部署它们,不管是在测试环境还是在生产环境;

同时,他在实践中也总结出,易分配的储存、标准的 RPC等因素也是决定一个微服务成败的先决条件,所以,Phil Calçado列出了关于微服务先决条件的完整清单如下(按照优先级从上到下):

  • 计算资源的快速分配
  • 基本的监控
  • 快速部署
  • 易于分配的存储
  • 易于访问的外围
  • 认证和授权
  • 标准化的 RPC

Reference:

  1. 微服务之间如何调用最佳?
  2. 花了一个月时间梳理了一下公司的微服务核心架构,原来也不是太难…