微服务架构学习1:概论

微服务,架构

Posted by Chris on March 1, 2020

1 微服务出现的背景

最初,许多企业服务的内部实现都是单体架构的。如下图所示,下图是《微服务架构设计模式》提供的虚构的某订餐企业的系统架构图,该架构提供的服务包括餐厅管理、订单管理、配送管理、支付、通知和结算。通过REST API和Web页面的方式来让送餐员、消费者和餐馆使用,通过一些适配器来使用外部的数据库、消息服务、邮件服务和支付服务。该系统内部是模块化的,但是该应用在部署的时候还是被打包为一个WAR包,并部署和运行到tomcat上,所以这是一个单体架构的系统。

单体架构有如下好处:

  • 开发简单
    RD只需要维护一个项目
  • 部署简单
    RD只需要将一个WAR包复制到安装了tomcat的服务器。(在SOA或者微服务中,对于一个功能的更改,很可能涉及部署多个服务。)

单体架构在使用的过程中,渐渐的发现了单体地狱的问题。什么是单体地狱呢,主要体现为单体巨大导致的如下这些问题:

  • 可维护性:过度的复杂性会让RD难以维护
    该单体过于复杂,以至于RD难以了解该系统的全貌。此外,多个团队维护一个项目,不利于项目的维护,导致职责不清。
  • 持续集成、持续部署和持续发布的问题:开发速度慢,部署速度慢
    单体过于巨大,导致每次编辑(项目巨大导致IDE慢)、构建、运行和测试这几个步骤花费的时间较长,降低开发的速度。由于单体过于巨大,导致提交代码后的自动化测试都运行很长时间,部署和上线也花费很长时间,大大降低了交付的速度。
  • 可靠性:交付可靠的单体应用存在挑战
    因为如下两个原因导致了可靠性的问题:1)单体巨大,不可能全部覆盖和运行所有的自动化测试,导致有些功能缺乏测试就进入线上环境;2)单体之间都共享同一个JVM或者机器资源,导致业务之间缺乏故障隔离。例如某段代码的内存泄露,耗尽机器资源,导致单体的所有业务都崩溃。
  • 可维护性:需要长期依赖于某个可能已经过时的技术栈
    单体架构在采用新的框架和编程语言是风险较高的,维护项目的RD不得不很可能一直采用老的过时的框架和语言。重构整个项目需要消耗巨大的人力,又可能引入较多的bug。

后来,人们渐渐发现,单体架构不容易做到代码/服务复用。于是,提出了SOA(service-oriented architecture,面向服务的架构)的概念,做到尽可能的服务共享。传统的SOA有如下的特点:

  • 重点是业务功能的复用
  • 有统一的治理和标准
  • 使用ESB(Enterprise Service bus,企业服务总线)协议来通信
  • 支持多种消息协议

根据功能复用的原则,传统的SOA会对单体进行拆分。因此,SOA解决了单体巨大的问题。看起来很完美,但SOA存在如下问题:

  • 在单体拆分上,没有理论指导
  • 存储仍然采用同一份,没有将数据存储也一起拆分

在SOA的基础上,结合很多软件大师对于SOA的研究,包括Eric Evans对于领域驱动设计的研究,Martin Fowler提出了微服务的概念。微服务可以认为是对SOA进行了改良:

  1. 采用领域驱动设计来拆分服务,而不是根据功能服务用的原则。当然,拆分服务的副作用之一是功能复用。
  2. 每个根据业务拆分的微服务都需要有自己的数据存储,不能和其他业务共享同一个数据库。

因此,我们会发现其实微服务和SOA很像,甚至可以认为微服务其实就是SOA 2.0(SOA的改良版),对于SOA的服务拆分有了具体的指导。这里,我们讲的也是SOA 2.0的内容。

2 需要解决的问题

需要解决单体架构中出现的问题,包括以下这些

  • 单个项目代码复杂性太大的问题
  • 开发速度慢、部署速度慢的问题
  • 单体可靠性的问题
  • 代码技术栈难以灵活更换的问题

3 微服务做了哪些事情

微服务对于架构提出如下要求:

  • 服务拆分。按照业务能力或者子域拆分服务
  • 服务拆分之后,多个服务之间需要通信。服务之间采用同步RPC或者异步消息机制进行通信
  • 多个服务之间需要有服务发现机制
  • 多个服务之间需要解决相互依赖的可靠性,即限流和熔断机制
  • 使用Saga来解决数据一致性的问题 一个业务可能涉及多个服务的多个数据更改,这就涉及到分布式事务来解决数据的一致性问题。一种解决方式是使用Saga来解决,后面会提到。
  • 一个查询涉及多个服务的数据,需要解决数据查询的问题 可以使用API组合器和CQRS(Command Query Responsiblity Segregation,命令查询职责分离)模式来解决调用多个服务的问题。
  • 认证、授权、配置平台、监控、分布式追踪、设计等问题在微服务的情况下会有新的挑战

4 微服务解决了哪些问题

  • 单个项目代码复杂性太大的问题。每个团队维护一个业务功能。
  • 开发和部署速度慢的问题
  • 单体可靠性的问题 将单体根据子域拆分为多个服务,并通过限流和熔断等措施来保证可靠性。
  • 代码技术栈难以灵活更换的问题

参考

Microservices vs SOA: What’s the Difference?
浅谈微服务的来龙去脉