【Distributed System】SOA 与 MicroServices

Posted by 西维蜀黍 on 2019-08-04, Last Modified on 2022-12-10

要知道,我们对 SOA 概念的理解其实是在不断的变化。

SOA(Service Oriented Architecture,服务导向架构)

从最初的 SOA 概念来说,SOA 主要为了解决一个大系统中不同子系统的相互操作性(interopearability),即为了实现这个大系统,我们希望能够复用已经存在或者说已经开发好的小系统(它们可能基于不同的编程语言,甚至运行在不同的操作系统下)。因此,这也可以描述为系统的集成(integration)问题。

因此,在那时候,我们有了 ESB (Enterprise Service Bus,企业服务总线)、WSDL、BPEL 和 SOAP 等等这些概念。它们都是为了解决系统的集成问题而诞生的。

企业服务总线(Enterprise Service Bus,ESB)

**企业服务总线(Enterprise Service Bus,ESB)**的概念是从服务导向架构(Service Oriented Architecture, SOA)发展而来。SOA描述了一种IT基础设施的应用集成模型;其中的软构件集是以一种定义清晰的层次化结构来相互耦合。一个ESB是一个预先组装的SOA实现,它包含了实现SOA分层目标所必需的基础功能部件。

在企业计算领域,企业服务总线是指由中间件基础设施产品技术实现的、 通过事件驱动和基于XML消息引擎,为更复杂的面向服务的架构提供的软件架构的构造物。企业服务总线通常在企业消息系统上提供一个抽象层,使得集成架构师能够不用编码而是利用消息的价值完成集成工作。

需要明确的是,企业服务总线本质上解决的是一个大系统的集成问题,或者说这个大系统中不同子系统之间相互依赖的问题。

场景

Background

假设一下你通过银行前端的应用登入银行,会发生什么呢?

  1. 会显示你的名字
  2. 会显示你的账号余额
  3. 会展示你的信用卡和借记卡
  4. 会列出你的共同基金
  5. 会列出一些你可能感兴趣的,预先被计算好的,有吸引力收益的借贷产品

现在,很可能所有这些模块都来自于不同的系统和应用,通过各种接口把数据展示出来

  1. 是来自在linux和Oracle的CRM系统
  2. 是来自z/OS大型机的COBOL系统
  3. 据说是来自大型机,但是他们的嘴巴很紧,不肯告诉你任何事情,只提供CSV文件。
  4. 来自跑在Windows的混合着PHP和Ruby
  5. 来自Postgresql,Python和Java,跑在Linux和Solaris的

在下图,每条不同宽度或者样式的线表示了app之间的调用

如果你觉得上面这种情况你还可以勉强维护,那下面这种情况呢?

你可以处理400个吗?2000个怎么样?每个应用都有自己独特的生态系统,都需要用10个物理服务器或者设备跑在上面。所以,就好比有2万个移动的群体散落在大陆上,并且有着各自的技术的或者文化的边界。 所有这些群体彼此之间需要不断的,持续的交换信息,聊天,一刻也停不下来。

对这种情况,有个很好的名字,叫一团糟。

使用SOA架构,用ESB提供服务

当你理解系统并不直接交换信息,理解什么是服务,那么现在你可以开始使用ESB了。

ESB的工作就是提供和调用集成系统的服务。使用了ESB,在大多情况下,每个系统和ESB之间,只需要定义一个访问方法,一个接口。如果这样,像上面的表一样,你有8个系统,就会有16个接口(1个方向1个)需要被创建、维护、管理和关注。

如果没有ESB,你就需要56个接口需要去思考和处理。(假设每个系统都需要跟其他系统对话)少了40个接口意味着少花时间和金钱。这就是你周末不用那么神经紧张的原因之一。

基于这个事实,你应该迫切地考虑需要引进ESB。

如果一个系统需要重写,改变所有者,生产商或者部门分拆,这个是ESB的工作去处理这个变更。其他的系统都甚至不需要周知,因为他们与ESB的接口不变。

SOA 的不断演化

再后来,我们抛弃了基于 XML 的 SOAP,因为使用 XML 实在是太繁重(虽然 XML 有 XML schema,可以非常规范的定义 Web Service 的 IDL)。我们转而开始使用基于 **RESTful(REpresentational State Transfer)**风格的Web Service。

再后来,我们又由了**微服务(Microservices)**的概念。

这个词本身起源于2011年5月在威尼斯附近举行的软件架构师研讨会。他们第一次使用“微服务”这个术语来描述参与者看到的一个共同的架构风格,其中许多参会者都在探索相似的内容。2012年5月,同一个团队决定将“微服务”作为最合适的名称。然而实际上,微软、亚马逊、Netflix和Facebook等主要的科技公司已经在微服务架构方面工作了十多年。

乍一看,微服务架构似乎谈论的是与SOA相同的事情。不过,如果引用微软服务领域的先驱Martin Flower的话,他曾经说过,“我们应该把SOA看作微服务的超集”。

SOA 微服务架构
应用程序服务的可重用性的最大化 专注于解耦
系统性的改变需要修改整体 系统性的改变是创建一个新的服务
DevOps和持续交付正在变得流行,但还不是主流 强烈关注DevOps和持续交付
专注于业务功能重用 更重视“上下文边界”的概念
通信使用企业服务总线ESB 对于通信而言,使用较少精细和简单的消息系统
支持多种消息协议 使用轻量级协议,例如HTTP,REST或Thrift API
对部署到它的所有服务使用通用平台 应用程序服务器不是真的被使用,通常使用云平台
容器(如Docker)的使用不太受欢迎 容器在微服务方面效果很好
SOA服务共享数据存储 每个微服务可以有一个独立的数据存储
共同的治理和标准 轻松的治理,更加关注团队协作和选择自由

微服务与SOA相比,更强调分布式系统的特性,比如横向伸缩性,服务发现,负载均衡,故障转移,高可用。互联网开发对服务治理提出了更多的要求,比如多版本,比如灰度升级,比如服务降级,比如分布式跟踪,这些都是在SOA实践中重视不够的。

微服务和SOA的区别

短答案:微服务是SOA发展出来的产物,它是一种比较现代化的细粒度的SOA实现方式。

微服务就是这样的一个「概念」,说白了,它不过就是近些年火起来的有一个名词而已,一时间仿佛整个行业都在讨论它,仿佛终于找到了银弹。这个时候SOA看待微服务大概就如同当年的Friendster和Myspace看待Facebook一样——大家都忘了社交网络这个东西并不是Facebook发明的。你再谈如何使用SOA去构建一个系统,就像是在谈一个过气的明星,人们会认为你已经落伍了。但真的是这样的吗?


较早实践微服务的公司Netflix就曾经称他们构建的架构是「细粒度的SOA」

讨论「微服务和SOA的差别」的意义远不如讨论「微服务和单体系统的差别」更大,因为他们的区别实在有点微妙。此外,互联网近些年的发展,越来越朝去中心化的方向前进了,就像今天的IT工程师不需要像律师、教师那样,需要得到某些机构的认可才能更好的开展工作,这一方面意味着门槛的降低,另一方面也意味着更多的概念没有一个权威的声音来对它进行定义,使得每个人可以根据自己的需求做出不同的调整。

微服务和SOA都是这样背景下的产物,并没有一个权威的定义,来说明它们各自包含了什么东西,使用什么的方法进行系统的构建。但是,还是可以从最大的范围来对比它们的不同,当我们今天说出这两个概念时,其区别往往没有那么大,但SOA是有一定的历史了,在历史上的SOA往往意味着更多的东西,而这些是现在很多人在做架构设计时不会采用的。

SOA到微服务

从SOA到微服务架构的迁移,最典型的例子就是将一个单体(Monolithic)应用重构为一个 Microservices 应用。

在单体(Monolithic)应用中,所有的功能打包在一个 WAR包里,基本没有外部依赖(除了容器),部署在一个JEE容器(Tomcat,JBoss,WebLogic)里,包含了 DO/DAO,Service,UI等所有逻辑。

而在基于微服务的架构(Microservice Architecture)中,系统中的子系统是这样的。微服务的目的是有效的拆分应用,实现敏捷开发和部署。

微服务的优势

完全独立的微服务组件有助于实现完全自主的所有权,带来以下优势:

  • 敏捷性和生产力:开发微服务的团队可以完全理解代码库。他们可以在快得多的周期中与其他组件独立地构建、部署和测试代码库。因为微服务组件只是网络上的另一个组件,所以您可以采用最适合所需功能的语言或框架来编写它,并采用最合适的持久性机制。

    这种方法可显著减少要编写的代码量,使维护得到显著简化。它可以确保团队能够根据需要采用新技术或现有技术的新版本,而不是等待应用程序域的剩余部分跟上节奏。对于微服务粒度的定义,微服务组件应足够简单,以便在必要时在其下一次迭代中重写。

  • 可伸缩性:微服务开发团队可以在运行时与其他组件独立地扩展微服务组件,实现资源的高效使用和对工作负载变化的快速反应。从理论上讲,一个组件的工作负载可以转移到对任务最合适的基础架构上。它还可以与剩余组件独立地重新放置,以便充分利用网络位置。精心编写的微服务提供了非凡的按需可伸缩性,这一领域的早期创新者和采用者已证明这一点。这些微服务也得到了最佳布置,以便充分利用弹性功能,以富有成本效益的方式访问大量资源的原生云环境。

  • 恢复能力:独立的运行时可以立即提供与其他组件中的故障独立的恢复能力。借助小心地解耦的设计,比如避免同步依赖关系和使用断路器模式,可以编写每个微服务组件来满足自己的可用性需求,而不是在整个应用程序域中引入这些需求。容器等技术和轻量型运行时使微服务组件能够快速且独立地失败,而不是让所有不相关的功能区域都失效。同样地,它们是以一种高度无状态的方式编写的,以便可以立即重新分布工作负载并几乎同时地调出新运行时。

Reference