jjzjj

「萌新指南」SOA vs. 微服务:What’s the Difference?

飞天小牛肉 2023-03-28 原文

实话实说,在我还没有实习之前,我是连 SOA 是啥都不知道的,只听说过微服务,毕竟微服务实在太火了,想不知道都难,我觉得实习的时候肯定也是微服务,进组之后发现是 SOA 架构,当时都懵了,看了很多文档做了很多笔记都还是不太明白 SOA 是啥,后来又困惑于 SOA 和微服务的区别是啥,我还去翻了一下《凤凰架构》这本书,遗憾的是,由于我刚刚接触 SOA,微服务也没有实际上手过,所以尽管周志明老师的文字已经非常小白向,但是我还是没能懂 SOA 和微服务到底有啥实质上的区别。

这俩天看见了 IBM 的一篇文章,真的醍醐灌顶,本文对这篇文章的部分段落进行翻译,然后结合之前看过的资料加入一些自己的理解,原文地址在这里,感兴趣的小伙伴可自行去阅读英文原文哈:https://www.ibm.com/cloud/blog/soa-vs-microservices

什么是 SOA

SOA 的全称是 Service-Oriented Architecture面向服务的架构。注意这是一种架构哈,我刚开始还以为是跟 Dubbo 一样的这种框架,hhh,这里为我的无知道歉。

SOA 是一种全企业范围(enterprise-wide)的应用软件开发方法,其核心在于利用可重复使用的软件组件(software components)或服务(services)。在 SOA 软件架构中,每项服务都由执行特定业务功能所需的代码(code)和数据集(data integrations)组成

In SOA software architecture, each service is comprised of the code and data integrations required to execute a specific business function

更通俗点来说,SOA 就是把系统按照实际业务拆分成刚刚好大小的、合适的、独立部署的模块,各个模块包含各自所需的代码和数据集,并且每个模块之间相互独立。

? 举个例子,一个银行网站可能会包含以下几种服务:检查客户的信用、登录网站或处理抵押贷款申请。这三种服务分别包含与各自业务相关的代码和数据集。

从代码层面直观来说,每个服务由以下三个部分组成:

  1. interface 接口:暴露给消费者使用的接口
  2. contract 契约:规定了服务提供者和服务消费者应该如何互动
  3. implementation 接口实现:接口的具体实现

SOA 于 20 世纪 90 年代末出现,是应用开发和集成发展的重要阶段。在 SOA 架构火起来之前,将单体应用程序(monolithic application)与另一个系统中的数据或功能连接起来需要复杂的点对点集成(point-to-point integration),并且一旦出现一个新项目,开发人员又得为这个新开发项目重新创建这些集成。而通过 SOA 将这些通用功能暴露出来(或者说共享出来),开发人员就无需每次都要重新写一遍重复代码了。

当然,这种方式既是一种好处,也是一种风险。由于很多应用程序都共享访问了某个服务,那如果这个服务出现问题了,这些应用程序也会受到级联影响。

? 举个通俗点的例子:(来自知乎高赞,稍作修改:光太狼 - https://www.zhihu.com/question/42061683)

比如现我有一个数据库,一个 JavaWeb 的网站客户端,一个安卓 App 客户端,一个 IOS 客户端。

现在我要从这个数据库中获取注册用户列表,如果按照单体应用程序的设计思想,那么就是这样的思路:JavaWeb里面写一个查询方法从数据库里面查数据然后在网页显示,安卓 App 里面写一个查询方法查询后在 App 上显示,IOS 同样如此。这样,同样的一套查询方法出现了三次,代码非常冗余,三个地方都有相同的业务代码,如果需要改动的话三个地方都要改,而且要改的一模一样。当然问题不止这一个。

于是乎出现了这样的设计思想,比如用 Java(或者是其他语言皆可)单独创建一个工程部署在一台服务器上,并且写一个方法(或称函数)执行上述查询操作,然后使其他人可以通过某种途径(可以是 HTTP 链接,或者是基于 Socket 的 RPC 调用)访问这个方法得到返回数据,返回的数据类型是通用的 JSON 或者 Xml 数据,就是说把这个查询操作封装到一个工程中去,然后暴露访问该操作的方式,形成 “服务”(服务接口)

这样一来,JavaWeb 这边可以访问这个服务然后得到数据使用,安卓和 IOS 这里也可以通过这个服务得到数据。而且最重要的是,要修改关于注册用户的业务方法只要改这个服务就好了,很好的解耦。同理,其他业务比如商品、广告等业务都可以单独形成服务部署在单独服务器上。

还有一种情况就是一旦哪天突然有一堆人要注册,假设这堆人仅仅只是注册而不做其他事情,其他业务比如商品、广告服务等都不忙,唯独注册这个服务压力很大,而原有的一台部署了注册服务的服务器已经承受不了这么高的并发,这时候就可以单独集群部署这个注册服务,提供多几台服务器提供注册服务,而其他服务不用动,维持原样就好了。


当然,以上举的例子其实并不能完全称为 SOA,还不够完整,因为它少了 服务治理 这一环节。

什么是服务治理,就是当服务越来越多,调用方也越来越多的时候,它们之间的关系就变得非常混乱,需要对这些关系进行管理。

还是上面的例子,假如我有一个用户服务,一开始有调用方 1 和调用方 2 来使用这个服务,后来越来越多,将近上百个调用方,这个时候作为服务方,它只知道提供服务,却不知道具体为谁提供了服务。而对于开发者来说,知道这 N 个调用方和 N 个服务方之间的关系是非常重要的。

所以这个时候就需要能进行服务治理的框架,比如 Dubbo + Zookeeper、Spring Cloud 等,有了服务治理功能,我们就能清晰地看到服务被谁谁谁调用,谁谁谁调用了哪些服务,哪些服务是热点服务需要配置服务器集群,而对这个服务集群的负载均衡也是服务治理可以完成的重要功能之一。

这个时候就是更加完善一点的 SOA 了。当然,还可以更进一步,加上 服务监控跟踪 等等之类的。

什么是微服务

? 直接举例:一个在线购物网站会有一些不同的功能,比如产品目录、购物车和下单等等。

使用 SOA 的开发公司一般会将购物网站拆分成主要的业务逻辑组,并将每个部分作为独立应用分别开发,最后集成到一起。具体开发流程包括事先定义好需要暴露给外部调用的服务接口,比如添加购物车操作和下单操作,然后围绕服务接口进行开发。

这样,如果其他应用比如火车票模块也需要下单操作,那么直接调用这个服务接口就行了,不用重新添加

各位应该能看出 SOA 这里存在的一个问题,那就是由于围绕主要的业务逻辑来划分,所以 SOA 的粒度是比较大的。比如说,我们现在围绕添加购物车和下单这两个主要业务逻辑定义了两个服务接口,但是添加购物车和下单这两个服务中都存在显示商品名称这种粒度比较小的通用功能,这样,我们就不得不在这两个服务接口中写一套差不多的代码。

使用微服务架构的开发公司会将购物车切分成较小的任务导向服务,不再是购物车应用了,而可能是显示商品名称服务、添加/移除商品服务、运费服务、汇率服务和订单撰写服务。购物车功能可能也会用到一些常用的服务——它们会用在这整个购物网站的很多地方,比如显示商品名称服务、显示产品图片服务、查看库存服务等。通用代码被封装成各种服务,待需要时用在各种功能中。

看下面这张网图,虽然有点不清晰,但是真的很通俗易懂了 ?:

SOA 和微服务的主要区别:范围

相信大家看完上面的例子也能够理解了。

这两种方法的主要区别归结于范围 scope。简单地说,服务型架构(SOA)粒度比较大,服务于企业范围,而微服务架构粒度比较小,服务于应用范围。

所以 If you accept the difference in scope, you may quickly realize that the two can potentially complement each other, rather than compete.

两者是相互补充,而不是竞争

? 关注公众号 | 飞天小牛肉,即时获取更新

  • 博主东南大学硕士在读,携程 Java 后台开发暑期实习生,利用课余时间运营一个公众号『 飞天小牛肉 』,2020/12/29 日开通,专注分享计算机基础(数据结构 + 算法 + 计算机网络 + 数据库 + 操作系统 + Linux)、Java 技术栈等相关原创技术好文。本公众号的目的就是让大家可以快速掌握重点知识,有的放矢。关注公众号第一时间获取文章更新,成长的路上我们一起进步

  • 并推荐个人维护的开源教程类项目: CS-Wiki(Gitee 推荐项目,现已累计 1.8k+ star), 致力打造完善的后端知识体系,在技术的路上少走弯路,欢迎各位小伙伴前来交流学习 ~ ?

  • 如果各位小伙伴春招秋招没有拿得出手的项目的话,可以参考我写的一个项目「开源社区系统 Echo」Gitee 官方推荐项目,目前已累计 900+ star,基于 SpringBoot + MyBatis + MySQL + Redis + Kafka + Elasticsearch + Spring Security + ... 并提供详细的开发文档和配套教程。公众号后台回复 Echo 可以获取配套教程,目前尚在更新中。

有关「萌新指南」SOA vs. 微服务:What’s the Difference?的更多相关文章

  1. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  2. ruby - what is - gets is a directory - 错误信息 - 2

    我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay

  3. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  4. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  5. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

  6. ruby-on-rails - rails 2.3.8, ruby 1.8.6 : Getting a visual call tree/graph of what methods call what? - 2

    我有一个中等复杂度的Rails应用程序。主Controller(执行应用程序所要做的事情的Controller)只有一个操作方法。(它不是标准的RESTful应用程序;它充当中介,并且对其调用方式有外部限制。)但是,它确实有很多方法和一些过滤器,以及一个不断增长的测试套件。随着时间的推移,结构发生了很大变化,我不再相信为之前编写的测试设置的某些Mocha期望仍然合适。有多个人在开发该应用程序,因此我正在构建一本用于编写功能测试的指南。“当你想在有/没有[那些]副作用的情况下进行测试时,使用[这些]期望和断言”等等。调用树/图在编写此类文档时非常有用。除了过滤器之外,这些甚至可以静态地从

  7. ruby - 使用指南针安装 bootstrap sass - 2

    我正在尝试安装bootstrap-sass并收到以下错误。我试过旧版本的sass,但bundler一直在安装3.3.0。WARN:UnresolvedspecsduringGem::Specification.reset:sass(~>3.2)WARN:Clearingoutunresolvedspecs.Pleasereportabugifthiscausesproblems./Library/Ruby/Gems/2.0.0/gems/compass-0.12.2/lib/compass/sass_extensions/monkey_patches/browser_support.r

  8. JMockit 使用指南 - 2

    目录配置模拟模拟类型与实例期望录制-回放-验证指定调用计数验证指定自定义结果验证调用参数联级模拟部分模拟模拟未实现的类其他伪装伪装方法及类伪装未实现类本文主要内容如何在SpringBoot中配置使用JMockit如何mock/faking依赖的对象如何对行为mock如何VerificationJMockit之所以强大,是因其使用了javaagent对类的字节码做了修改,在JVM的所有mock工具中,它是功能最强大的。同时注解又是最少的。配置在SpringBoot项目中使用JMockit隔离代码做单元测试,需要做以下配置引入JMockit依赖。dependencies>dependency>gr

  9. ruby-on-rails - 是否有针对经验丰富的 Ruby 开发人员的 Rails 指南? - 2

    几年前,我从一些Rails初学者指南开始学习Ruby/Rails。那时我已经学习了Rails的基础知识,例如模型和路由的一些约定优于配置,以及如何使用helpers等。但是,我并没有坚持多久,因为此后不久我发现了Sinatra,并决定我个人更喜欢它。不过,我最终真的爱上了Ruby,从那以后我写了很多Ruby,几乎没有一个是针对任何Rails项目的。然而,事实证明大部分可用的Ruby工作都是针对Rails应用程序的。所以我现在想再尝试一下Rails。现在,该引用资料很棒并且有很多有用的信息,但我只查看了我需要的特定内容的引用资料,而没有记住。但我不太可能在引用资料中看到像script/c

  10. ruby-on-rails - 修改 Rails : How do advanced users find out what needs to be changed? - 2

    我已经使用Rails几个月了,我很乐意编写一个项目并根据我的需要操作Rails等。最近我一直在尝试更高级一些,所以我尝试修改/添加到现有的Rails代码库:添加新的表单辅助方法、添加responds_to:pdf方法等...然后我遇到了很多问题。困难在于学习我需要修改哪些代码;该代码所在的位置,以及如何确保我不会错过其他文件中的相关代码。我猜人们有办法学会这样做,但目前我主要只是猜测和希望。我想我的问题是,Rails人员如何了解他们需要修改的代码在哪里编辑以及编辑代码的方法?看起来这只是您需要先熟悉的东西,但我猜必须有一种简单的方法来理解在哪里(和什么)编辑。任何想法表示赞赏.....

随机推荐