聊聊单体、SOA和微服务

SOA关注的是遗留系统的集成和组件重用,落地上依赖厂商的ESB方案。微服务在互联网时代兴起,使用领域驱动的思想划分服务边界,使得系统由大量高内聚、松耦合的服务组成,落地上可以使用多样化的技术方案。SOA体现了中心化的服务中心,微服务则是去中心分。

从单体应用说起

最初只有一个系统,对外提供简单的功能。随着业务发展,越来越多功能加入到系统。原来简单的系统,滚雪球一样变成巨大的单体应用。功能迭代变慢、部署复杂,开始拖累业务发展。

对于单体架构,常见的架构设计方式是分层。比如常见的MVC分层方式。分层的好处有:

  • 分离关注点(separation of concern),降低复杂度。
  • 层与层之间的交互,只要定义好接口,实现高内聚松耦合。可以方便替换层里面的实现。
  • 部分分层部署。比如nodejs做view层渲染,不用在jsp里面折腾。

但还是水平切分。部署的时候,还是一个整体应用部署,牵一发而动全身:

  • 某个模块升级,影响整个应用
  • 某个业务升级,影响整个应用
  • 某个升级带来的故障,影响整个应用

正因为单体应用部署的风险大,会有复杂、严格的流程限制部署频率。结果是迭代缓慢、单次升级内容巨大。 解决单体应用的问题,关键是垂直切分。把一个大的单体应用,根据业务切分为多个应用。这就产生了SOA和微服务。

SOA和微服务的共同点

SOA(Service Oriented Architecture)和微服务架构(Micro Service Architecture,MSA)的共同点:

  • 都包含了服务化的理念,微服务是SOA的升华
  • 支持跨语言平台

但除此之外,二者的区别比较大。本文的关注点是比较二者的不同。

诞生背景

SOA源于解决遗留异构系统的集成和组件重用。 企业信息化过程中,产生了各种各样的业务系统(CMS、CRM、ERP、TMS等)。这些系统往往是技术隔离的,采用不同的技术实现、不同的通信方式。可能是不同时期采购的系统,可能是企业并购带来的其他子系统。需要有一种方案把各种异构系统整合起来,实现更大的价值。 SOA的关键字:集成,组件重用,ESB

微服务在互联网产品时代兴起。因为业务要快速试错,变化很快,因此技术上要支持快速迭代、快速上线。 大型单体应用由于自身的复杂性,容易牵一发而动全身,做功能的新增修改都更加谨慎;同时为了避免风险,会有一系列复杂的部署流程,需要各个干系人同意,导致发布频率变低、单次变更内容更多。显然在一个大型单体应用上很难达到快速迭代、快速上线的要求。唯有在小型、独立的系统才更容易实现。服务划分是实现小型高内聚、松耦合系统的基础。 快速迭代的另一个重要条件是,对具体的业务采用合适的解决方案和技术栈。比如,脚本语言更适合做爬虫系统,java的技术栈更适合企业信息系统。因此,微服务同样是支持异构系统。 每个微服务能够独立迭代、部署的前提是,拥有服务的自治权。 一旦大规模采用微服务的架构思想,就要管理大量的小型服务,构建、测试、部署都必须自动化。 微服务的关键字:服务划分,自治性,自动化,独立部署,去中心化。

服务化

虽然微服务和SOA都提及服务化,但是二者有很大的区别。 因为SOA源于解决遗留系统的集成问题,因此更多是把子系统服务化,CRM是一个服务、ERP也是一个服务,然后invoke这些服务提供的接口。因此SOA的服务是粗粒的,服务尺寸比较大。

微服务吸收了领域驱动的思想,使用限界上下文(bounded countext)划分服务边界和职责。划分服务边界是实施微服务的关键,因为不好的服务划分,会导致服务臃肿、服务间紧耦合,不能达到微服务的好处。 “micro”表明了服务的粒度要小。那么多小的服务粒度才是合适?我的经验是,适配团队规模即可。如果只有3个研发,却拆分出20个微服务,扯淡去吧。

在SOA里,组件重用是服务化的原动力。既然都有现成的IT设施,那么就想办法继续使用。 在微服务,服务化不仅仅是为了功能重用,更重要是控制系统的复杂度。一个高内聚、专注某个业务的小型系统,要比一个涵盖多个不同领域的巨型单体系统容易理解,更加适合业务的快速迭代。

因为微服务是职责分明的小粒度服务,微服务之间通过bounded context交互即可,隐藏了服务内部的细节。但是SOAP是粗粒度的服务,往往意味着这个组件可能默默承担了更多的业务职责,对于想重用该组件的调用方来说,可能会带来意想不到的副作用。尽管SOA也提倡屏蔽服务细节,但是在实际中往往需要对其他组件有更多的了解。

小结:

  • 微服务强调按照业务领域拆分,具有一定业务能力的轻量服务。
  • SOA只是要求接口规范化、接口独立,是粗粒度的服务化,每一个功能都是通过一个独立服务来提供,服务定义了明确可以调用的接口,服务之间通过编排、协同交互,完成一个完整的业务功能。

异构系统

SOA和微服务都支持异构系统,但是原因很不一样。 SOA的异构,源于各个遗留系统采用了不同的IT技术,采用RMI、CORBA、HTTP乃至私有服务协议。 微服务的异构,源于为不同的业务场景,选择最合适的技术方案。但是异构的技术栈,会带来招聘、服务协同、内部人员流动的成本增加,在实践中要限制异构技术栈的数量。

异构系统需要解决发现、通信和互操作问题。 SOA的方案是一套基于XML的通用协作语言,包括UDDI服务发现、SOAP互操作、WSDL服务描述语言、BPEL服务编排语言等。在SOA流行的时代,XML是业界推荐的跨平台数据交互方式。在落地上,主要是各个不同vendor厂商的ESB(Enterprise Service Bus,企业服务总线)方案。为了实现某些特性,例如分布式事务,又要捆绑vendor的全家桶。因此,SOA实际是被vendor捆绑的。

ESB.svg

图片来源于wikipedia

微服务没有官方规定的方案,技术选型灵活。业界推荐使用语言无关的REST风格交互。或者是支持各个异构系统的RPC框架(thrift,protobuf等)。在服务发现上选择更多了,zookeeper、consul、eureka等是常见。

去中心化

各个系统通过接入ESB,依靠ESB完成服务发现、服务调用以及数据交换。这样做的好处是,现有系统的改造少,但是ESB的职责很重。ESB是各个服务的通信中心,是通信瓶颈。在业务上,依靠BPEL做服务编排(orchestration),实际上形成了服务中心大脑。整个SOA是中心化的。

微服务架构,是去中心化的。服务发现之后,服务之间通过更加高效的点对点(P2P)通信调用,没用通信总线的概念。在服务调用上,微服务鼓励使用协同(choreography)方式,避免形成服务中心大脑和服务之间的紧耦合。这样带来的问题是,业务流程和状态的跟踪和观察变得复杂。需要对业务流程更加深入的理解,以及更加强大的监控系统。

驱动力量

SOA更多的驱动力量是软件vendor厂商,推销自家SOA全家桶方案又大赚一笔,是自上而下的驱动。 微服务的驱动力量来自于底层的研发人员以及开源社区。互联网业务快速多变,原有单体架构上搬砖不能满足业务速度,挖坑踩坑血泪史无数,这些经验逐步形成了微服务的方法论,在业界形成自底向上的驱动力量。

独立部署

微服务架构强调独立部署,在落地上使用docker容器化、kubernete容器编排协同等技术。部署是限制微服务落地的一大门槛,因为容器化部署对运维团队要求很高。 为什么SOA并没有很关注部署?SOA面对的系统,通常已经稳定了,或者不好用、但是改不动(技术上或者组织结构上的原因),或者想改动、但是部署成本高;因此SOA架构的迭代周期缓慢。同时也体现SOA对重用组件的渴望,因为变更一个服务实在太艰难了。

小结:

  • 微服务强调独立部署,尤其是存储层的独立。共享数据库被认为是微服务的反模式!
  • SOA只要求接口独立,不要求内部实现独立部署。

其他

服务注册,服务发现,服务路由,安全访问和授权,分布式事务,监控等双方都是有的,只是实现不一样。

总结

SOA和微服务都是服务化的架构,这是二者的共同之处。但是二者对于服务的理解却不太相同,实际应用场景和实施也区别很大。因此有的观点说微服务是去掉ESB的SOA实现,并不是十分恰当。 在服务化架构中,SOA是1.0,微服务是2.0,service mesh是3.0。

Built with Hugo
Theme Stack designed by Jimmy