多研究些架构,少谈些框架

本贴最后更新于 2425 天前,其中的信息可能已经东海扬尘

2017-6-9 曹祖鹏 github.com/JoeCao/JoeCao.github.io/issues/3

微服务架构和 SOA 区别

微服务现在辣么火,业界流行的对比的却都是所谓的 Monolithic 单体应用,而大量的系统在十几年前都是已经是分布式系统了,那么微服务作为新的理念和原来的分布式系统,或者说 SOA(面向服务架构)是什么区别呢?

我们先看相同点:

  • 需要 Registry,实现动态的服务注册发现机制;
  • 需要考虑分布式下面的事务一致性,CAP 原则下,两段式提交不能保证性能,事务补偿机制需要考虑;
  • 同步调用还是异步消息传递,如何保证消息可靠性?SOA 由 ESB 来集成所有的消息;
  • 都需要统一的 Gateway 来汇聚、编排接口,实现统一认证机制,对外提供 APP 使用的 RESTful 接口;
  • 同样的要关注如何再分布式下定位系统问题,如何做日志跟踪,就像我们电信领域做了十几年的信令跟踪的功能;

那么差别在哪?

  • 是持续集成、持续部署?对于 CI、CD(持续集成、持续部署),这本身和敏捷、DevOps 是交织在一起的,我认为这更倾向于软件工程的领域而不是微服务技术本身;
  • 使用不同的通讯协议是不是区别?微服务的标杆通讯协议是 RESTful,而传统的 SOA 一般是 SOAP,不过目前来说采用轻量级的 RPC 框架 Dubbo、Thrift、gRPC 非常多,在 Spring Cloud 中也有 Feign 框架将标准 RESTful 转为代码的 API 这种仿 RPC 的行为,这些通讯协议不应该是区分微服务架构和 SOA 的核心差别;
  • 是流行的基于容器框架还是虚拟机为主?Docker 和虚拟机还是物理机都是架构实现的一种方式,不是核心区别;

微服务架构的精髓在切分

  • 服务的切分上有比较大的区别,SOA 原本是以一种“集成”技术出现的,很多技术方案是将原有企业内部服务封装为一个独立进程,这样新的业务开发就可重用这些服务,这些服务很可能是类似供应链、CRM 这样的非常大的颗粒;而微服务这个“微”,就说明了他在切分上有讲究,不妥协。无数的案例证明,如果你的切分是错误的,那么你得不到微服务承诺的“低耦合、升级不影响、可靠性高”之类的优势,而会比使用 Monolithic 有更多的麻烦。
  • 不拆分存储的微服务是伪服务:在实践中,我们常常见到一种架构,后端存储是全部和在一个数据库中,仅仅把前端的业务逻辑拆分到不同的服务进程中,本质上和一个 Monolithic 一样,只是把模块之间的进程内调用改为进程间调用,这种切分不可取,违反了分布式第一原则,模块耦合没有解决,性能却受到了影响。

分布式设计第一原则 — “不要分布你的对象”

  • 微服务的“Micro”这个词并不是越小越好,而是相对 SOA 那种粗粒度的服务,我们需要更小更合适的粒度,这种 Micro 不是无限制的小。

如果我们将两路(同步)通信与小/微服务结合使用,并根据比如“1 个类=1 个服务”的原则,那么我们实际上回到了使用 Corba、J2EE 和分布式对象的 20 世纪 90 年代。遗憾的是,新生代的开发人员没有使用分布式对象的经验,因此也就没有认识到这个主意多么糟糕,他们正试图重复历史,只是这次使用了新技术,比如用 HTTP 取代了 RMI 或 IIOP。

微服务和 Domain Driven Design

一个简单的图书管理系统肯定无需微服务架构。既然采用了微服务架构,那么面对的问题空间必然是比较宏大,比如整个电商、CRM。

如何拆解服务呢?

使用什么样的方法拆解服务?业界流行 1 个类=1 个服务、1 个方法=1 个服务、2 Pizza 团队、2 周能重写完成等方法,但是这些都缺乏实施基础。我们必须从一些软件设计方法中寻找,面向对象和设计模式适用的问题空间是一个模块,而函数式编程的理念更多的是在代码层面的微观上起作用。

Eric Evans 的《领域驱动设计》这本书对微服务架构有很大借鉴意义,这本书提出了一个能将一个大问题空间拆解分为领域和实体之间的关系和行为的技术。目前来说,这是一个最合理的解决拆分问题的方案,透过限界上下文(Bounded Context,下文简称为 BC)这个概念,我们能将实现细节封装起来,让 BC 都能够实现 SRP(单一职责)原则。而每个微服务正是 BC 在实际世界的物理映射,符合 BC 思路的微服务互相独立松耦合。

微服务架构是一件好事,逼着大家关注设计软件的合理性,如果原来在 Monolithic 中领域分析、面向对象设计做不好,换微服务会把这个问题成倍的放大。

以电商中的订单和商品两个领域举例,按照 DDD 拆解,他们应该是两个独立的限界上下文,但是订单中肯定是包含商品的,如果贸然拆为两个 BC,查询、调用关系就耦合在一起了,甚至有了麻烦的分布式事务的问题,这个关联如何拆解?BC 理论认为在不同的 BC 中,即使是一个术语,他的关注点也不一样,在商品 BC 中,关注的是属性、规格、详情等等(实际上商品 BC 这个领域有价格、库存、促销等等,把他作为单独一个 BC 也是不合理的,这里为了简化例子,大家先认为商品 BC 就是商品基础信息), 而在订单 BC 中更关注商品的库存、价格。所以在实际编码设计中,订单服务往往将关注的商品名称、价格等等属性冗余在订单中,这个设计解脱了和商品 BC 的强关联,两个 BC 可以独立提供服务,独立数据存储

小结

微服务架构首先要关注的不是 RPC/ServiceDiscovery/Circuit Breaker 这些概念,也不是 Eureka/Docker/SpringCloud/Zipkin 这些技术框架,而是服务的边界、职责划分,划分错误就会陷入大量的服务间的相互调用和分布式事务中,这种情况微服务带来的不是便利而是麻烦。

DDD 给我们带来了合理的划分手段,但是 DDD 的概念众多,晦涩难以理解,如何抓住重点,合理的运用到微服务架构中呢?

我认为如下的几个架构思想是重中之重

  • 充血模型
  • 事件驱动

之后将为大家详细介绍这两个设计思路。!

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3192 引用 • 8214 回帖 • 2 关注
  • 框架
    46 引用 • 346 回帖 • 1 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    143 引用 • 442 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 489 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 14 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 2 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    30 引用 • 108 回帖
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 259 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 656 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 2 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 1 关注
  • OneDrive
    2 引用 • 1 关注
  • Excel
    31 引用 • 28 回帖
  • webpack

    webpack 是一个用于前端开发的模块加载器和打包工具,它能把各种资源,例如 JS、CSS(less/sass)、图片等都作为模块来使用和处理。

    41 引用 • 130 回帖 • 253 关注
  • 996
    13 引用 • 200 回帖 • 10 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 76 回帖 • 2 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    581 引用 • 3535 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 3 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • Scala

    Scala 是一门多范式的编程语言,集成面向对象编程和函数式编程的各种特性。

    13 引用 • 11 回帖 • 154 关注
  • TextBundle

    TextBundle 文件格式旨在应用程序之间交换 Markdown 或 Fountain 之类的纯文本文件时,提供更无缝的用户体验。

    1 引用 • 2 回帖 • 71 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 1 关注
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 3 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 635 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖
  • 安全

    安全永远都不是一个小问题。

    204 引用 • 816 回帖
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 3 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    85 引用 • 165 回帖 • 5 关注