微服务系列之单体架构
Posted a_ittle_pan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务系列之单体架构相关的知识,希望对你有一定的参考价值。
随笔
终于迎来了“微服务、云原生”系列文章,这个系列的文章的更新速度博主无法保证能够每个星期一篇,因为这个系列的难度比以往系列都要高(以往的系列就没有保证一个星期一更)。但是长时间不去写文章,自己可能会慢慢失去写作的能力与热情,因此,除了“微服务、云原生”系列的文章,博主会穿插“mysql”系列的文章。
参考书籍:
- “凤凰架构”
- 微服务架构设计模式
单体架构(Monolithic)
“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已
对于单体架构(又称巨石系统(Monolithic Application)),各位应该都不会太陌生,,可以说在“微服务架构”出现在大家的视野之前,市面上基本都是单体架构的软件。而单体这个概念其实是在“微服务”理念提出后所产生的,从概念诞生的先后顺序,我们也不难看出,“单体”与“微服务”是一组相互对比参照的概念。
我们深入了解单体架构之前,大家先思考一个问题:“单体架构是不是一种优秀的软件设计?”
可以不用着急下结论,深入了解单体架构之后再看这个问题,你会有不一样的感受。
下图是“微服务架构设计模式”中用来举例的单体项目架构:
这个应用的名字叫FTGO(Fod to Go的简称),核心业务为消费者 (C o n s u m e r ) 使用 F T G O 的网站或者移动应用在本地的餐馆 (R e s t a u r a n t ) 下订单, F T G O 会协调一个由送餐员 (C o u r i e r )组成的快递网络来完成订单食品(Order)的运送(Delivery)。
FTGO应用程序具有六边形架构。它由业务逻辑组成,业务逻辑外面是实现用户界西的适配器和与外部系统的接口,例如移动应用程序,支付、消息和电子邮件的云服务等(这种应用层面的架构设计是没有什么问题的,符合高内聚、低耦合等软件设计理念,可以称得上一个好的设计)。同时,这个应用会被整体打包成一个单一的WAR 文件,部署运行在Tomcat 之上(很典型的单体软件架构风格)。
听到这里,大家对这个系统应该是有一个比较直观的感受就是:如果系统业务非常的复杂,这个系统后期的war肯定非常的滴大。如果项目在我的ide上跑,可能索引就需要好几个小时,更不用说编译和运行了(博主亲身经历过🥹)。按照大家98年的脾气,可能刚进公司就已经准备跑路了~~
结合软件历史来说,这种系统架构在当时已经是最优选(此时还没有微服务这种概念),使用这种架构的软件系统在发展的早期,应用程序相对较小,会有以下好处:
- 应用的开发很简单:IDE和其他开发工具只需要构建这一个单独的应用程序(开发初期,后期如果业务复杂,此优势将不负存在)
- 易于对应用程序进行大规模的更改:可以更改代码和数据库模式,然后构建和部署。
- 测试相对简单直观:开发者只需要写几个端到端的测试,启动应用程序,调用RESTAPI , 然后使用 Selenium 日这样的工具测试用户界面。
- 部署简单明了:开发者唯一需要做的,就是把WAR文件复制到安装了Tomcat的服务器上。
- 横向扩展不费吹灰之力:FTGO可以运行多个实例,由一个负载均衡器进行调度
上面这么多优点,都是针对于项目初期来说的,随着时间的推移,整个系统的开发、测试、部署和扩展都会变得更加困难。至于为什么,我们接着往下面看。
上图是FTGO项目从开发到部署的一个整体流程,分析这个过程我们其实不难找到一些问题:
- 业务过于复杂导致开发人员难以理解系统的全部(校招员工:进公司两个月,我们公司的系统是干什么的?)
- 开发速度缓慢(员工:ide打开项目、编译、运行如果只要2分钟,那我开发速度肯定高)
- 从代码提交到实际部署的周期很长,而且容易出问题(开发:如果我头发还顶的住,那么我能够在指定时间内开发完。 项目测试:我测试一个功能最少需要2天,前提是开发写的代码没问题。 运维:我部署项目需要1天,前提是服务器配置高)
- 难以扩展(订单团队:我们模块是核心模块因此服务需要占用大量系统资源没问题吧 图片处理团队:我们功能需要比较快的CPU 来完成图形运算也是合情合理的)
- 交付可靠的单体应用是一项挑战(某开发人员:我艹,上回写的需求里面有一个OOM的bug,P0级故障,我要准备跑路了 )
- 需要长期依赖某个可能已经过时的技术栈(技术大牛: shit,我Golang白学了)
如果单从FTGO项目来分析单体架构,我们眼里看到的更多的是单体架构的不足。但是需要知道的是,在微服务架构出现之前,基本所有的公司都用的单体架构,如果单体架构那么不堪,怎么可能会有那么多企业的架构师会选择采用单体架构进行项目的开发呢?也就是说,衡量一个架构的好坏不能单靠一个案例就可以决定的。
假设现在公司想让你做一个业务相对简单的系统,你会选用单体架构还是微服务架构?
如果是我的话,我会首选单体架构,至于为什么,我从一下几个角度进行说明:
- 纵向角度(MVC分层架构):对于这个意义上的“可拆分”,单体架构完全不会展露出丝毫的弱势,反而可能会因更容易开发、部署、测试而获得一些便捷性上的好处。
- 横向角度(物理加服务器):单体架构也可以支持按照技术、功能、职责等维度,将软件拆分为各种模块,以便重用和管理代码。单体系统并不意味着只能有一个整体的程序封装形式,如果需要,它完全可以由多个 JAR、WAR、DLL、Assembly 或者其他模块格式来构成。即使是以横向扩展(Scale Horizontally)的角度来衡量,在负载均衡器之后同时部署若干个相同的单体系统副本,以达到分摊流量压力的效果,也是非常常见的需求
- 服务的性能消耗角度:一台服务器就可以满足业务需求
- 人员角度:开发此系统的开发人员规模没有超过“2 Pizza Team”的范畴
- 业务层面:业务简单,不需要进行业务拆分
架构之:微服务和单体服务之争
简介
微服务和单体服务的各自好处之前的文章中已经讲的很明白了。本篇文章不是探讨到底应该用哪种服务架构。而是假设项目最终会采用微服务架构,那么就会有两种情况,第一种情况下项目一开始的时候,是先使用单体服务然后在项目发展过程中逐渐转换成微服务,另外一种就是一开始就采用微服务的架构。
本文将会讨论一下采用这两种方式的原因。
先单体再微服务
微服务是一种有用的架构,但即使是他们的拥护者也表示,使用微服务只对更复杂的系统有用。
因为使用微服务本身是有一个管理上的服务成本,这个成本会减慢团队的开发速度。所以对于更简单的应用程序来说,使用单体服务更加简单。所以该方式的支持者认为应该在最初将新应用程序构建为单体应用,即使最后很有可能转换为微服务。
第一个原因是在系统的初期,我们并不知道它到底会有多少用户,并且在软件的第一个阶段,我们通常考虑的是软件开发的速度,所以大家可能更加倾向于使用单体应用。如果使用了微服务,如果该微服务的设计比较糟糕,那么会导致后续系统无法扩展,只能重新设计。
第二个原因是,只有在服务之间提出良好、稳定的边界时,它们才能很好地工作,服务之间的任何功能重构都比单体应用困难得多。但即使是在熟悉领域工作的经验丰富的架构师,在一开始就很难确定边界。通过首先构建一个单体服务,您可以弄清楚正确的边界是什么,从而在边界之上再进行微服务的转换。
一种将单体服务转换为微服务的做法是,将单体服务经过合理的设计,比如注意软件内部的模块化,包括 API 边界和数据存储方式。如果能够做好这一点,那么后续转向微服务是一件相对简单的事情。
另一种方法是从单体应用开始,逐渐剥离边缘的微服务。这种方法可以在微服务架构的核心留下一个庞大的单体,但大多数新的开发使用微服务,而单体应用不再进行扩展。
还有一种是完全替代单体应用。这样可以完全抛弃单体带来的架构负担,重新开始。代价就是需要多花人力和时间。
所以,如果你不能构建一个结构良好的单体应用,那么是什么让你认为你可以构建一组结构良好的微服务?
直接从微服务开始
当然,也有人持有不同的意见,因为他们认为:
如果你确实能够构建结构良好的单体应用,那么您可能一开始就不需要微服务。
也就是说,不管是单体服务还是微服务,在构建之前都需要进行详细的需求分析,经过了透彻的分析,那么是否需要使用微服务一键很了解了,各个服务的边界也被界定出来了,那么为什么不直接使用微服务呢?
微服务的主要好处就是在不同的服务之间建立了一个边界。这样我们很难弄错一些事情,比如连接不应该连接的部分,并耦合那些不应该被耦合的部分。
在理论上,如果你的程序遵循了特定的规则,并在整体应用程序中建立明确的界限,那么您不需要微服务,但是在实际的工作中,这个界限总是会被跨域。
你可能会假设有许多可以被很好地分离的微服务隐藏在你的单个项目中,等待被提取。但实际上,很难进行这样的划分。
如果你从一个整体开始,各个部分将变得非常紧密地相互耦合。这就是单体应用的定义。这些部件将依赖于它们都使用的平台的特性。它们将基于共享的抽象进行通信,因为它们都使用相同的库。他们将使用仅当它们托管在同一进程中时才可用的方式进行通信。更糟糕的是,这些部分将(几乎)自由地共享域对象,依赖相同的共享持久性模型,假设数据库事务随时可用,因此无需补偿……从而使得再次分割事务变得非常困难。所以将现有的单体拆分成单独的部分非常困难。
所以当你开始时,就应该考虑你构建的子系统,并尽可能独立地构建它们。当然,只有在您认为您的系统大到足以保证这一点时才应该这样做。如果只有您和您的一位同事在几周内构建了一些东西,那么您完全不需要使用微服务。
总结
软件架构的世界总是很有趣,我们在探索的过程中也会学到很多不一样的视角。
本文已收录于 http://www.flydean.com/10-microservices-monolith/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
以上是关于微服务系列之单体架构的主要内容,如果未能解决你的问题,请参考以下文章
Chris Richardson微服务翻译:构建微服务之微服务架构的进程通讯