vlambda博客
学习文章列表

一线互联网架构师,带大家深入学习微服务架构的设计原则,快上车

前言

当我们从单体架构的应用走向基于微服务的架构时,首先面临的一一个问题是如何来进行拆分。同时还需要考虑服务颗粒度的问题,即服务多小才算是“微”。接着需要做一个重要的决定, 就是如何将这些服务都连接在一起, 诸如此类。下面就带领大家一起来看看微服务的架构设计原则。

拆分足够微

在解决大的复杂问题时,我们倾向于将问题域划分成若干个小问题来解决,所谓“大事化小,小事化了”。单体架构的应用,随着时间的推移,会越来越臃肿,适当地做“减法”,可以解决单体架构存在的问题。

将单体架构的应用拆分为微服务时,应考虑微服务的颗粒度问题。颗粒度太大,其实就是拆分得不够充分,无法发挥微服务的优势;如果拆分得太细,又会面临服务数量太多引起的服务管理问题。对于如何“微”才算是足够的“微”,这个业界也没有具体的度量, Sam Newman给出的建议是,“small enough and no smaller(足够小即可,不要过小)”田。当开发人员认为自己的代码库过大时,往往就是拆分的最佳时机。代码库的大小不能简单地以代码量来评价,毕竟复杂业务功能的代码量,肯定比简单业务的代码量要高。同样地,一个服务,功能本身的复杂性不同,代码量也截然不同。

一个经验值是,一个微服务通常能够在两周内开发完成,且能够被一个小团队所维护;否则,则需要将代码进行拆分。

微服务也不是越小越好。服务越小,微服务架构的优点和缺点也就会越来越明显。服务越小,微服务的独立性就会越高,但同时,微服务的数量也会激增,管理这些大批量的服务也将会是一个挑战。

轻量级通信

在单体架构的系统中,组件通过简单的方法调用就能进行通信,但是微服务架构系统中,由于服务都是跨域进程,甚至是跨越主机的,组件只能通过REST、Web 服务或某些类似RPC的机制在网络.上进行通信。

服务间通信应采用轻量级的通信协议,例如,同步的REST,异步的AMQP、STOMP、MQTT等。在实时性要求不高的场景下,采用REST服务的通信是不错的选择。REST基于HTTP协议,可以跨越防火墙的设置。其消息格式可以是XML或JSON,这样也方便开发人员来阅读和理解。

如果对通信有比较高的要求,则不妨采用消息通信的方式。

领域驱动原则

应用程序功能分解可以通过Eric Evans在领域驱动设计( Domain-Driven Design) 一书中明确定义的规则实现。

一个微服务,应该能反映出某个业务的领域模型。使用领域驱动设计(DDD),不但可以降低微服务环境中通用语言的复杂度,而且可以帮助团队搞清楚领域的边界,理清上下文边界。

建议将每个微服务都设计成一个DDD限界上下文( Bounded Context) 。这为系统内的微服务提供了一个逻辑边界,无论是在功能,还是在通用语言上。每个独立的团队负责-一个逻辑上定义好的系统切片。每个团队负责与一个领域或业务功能相关的全部开发,最终,团队开发出的代码会更易于理解和维护。

单一职责原则

当服务粒度过粗时,服务内部的代码容易产生耦合。如果多人开发同-一个服务, 很多时候因为耦合会造成代码修改重合,开发成本相对也较高,且不利于后期维护。

服务的划分遵循“高内聚、低耦合”,根据“单一职责原则”来确定服务的边界。

服务应当弱耦合在一起,对其他服务的依赖应尽可能低。一个服务与其他服务的任何通信都应通过公开暴露的接口(API、事件等)实现,这些接口需要妥善设计以隐藏内部细节。

服务应具备高内聚力。密切相关的多个功能应尽量包含在同- -个服务中, 这样可将服务之间的干扰降至最低。服务应包含单- -的界限上下文。界限上下文可将某-领域的内部细节, 包括该领域特定的模块封装在-一起。

理想情况下,必须对自己的产品和业务有足够的了解才能确定最自然的服务边界。就算一开始确定的边界是错误的,服务之间的弱耦合也可以让你在未来轻松重构(如合并、拆分、重组)。

DevOps及两个披萨

每个微服务的开发团队应该是小而精,并具备完全自治的全栈能力。团队拥有全系列的开发人员,具备用户界面、业务逻辑和持久化存储等方面的开发技能及能够实现独立的运维,这就是目前流行的DevOps的开发模式。

团队的人数越多,沟通成本就会越高,工作的效率就越低下。Amazon 的CEO Jeff Bezos对如何提高工作效率这个问题有自已的解决办法。他称之为“两个披萨团队( Two Pizza Team)”,即- -个团队人数不能多到两个披萨饼还不够他们吃的地步。

“两个披萨原则”有助于避免项目陷入停顿或失败的局面。领导人需要慧眼识才,找出能够让项目成功的关键人物,然后尽可能地给他们提供资源,从而推动项目向前发展。让-个小团队在一起做项目、开会研讨,更有利于达成共识,促进企业创新。

Jeff Bezos把披萨的数量当作衡量团队大小的标准。如果两个披萨不足以喂饱-个项目团队,那么这个团队可能就显得太大了。合适的团队一般为六七人。

不限于技术栈

在单体架构中,技术栈相对较为单- -。而在微服务架构中,这种情况就会有很大的转变。

由于服务之间的通信,是跟具体的平台无关的,所以理论上,每个微服务都可以采用适合自己场景的技术栈。比如,某些微服务是计算密集型的,那么可以配备比较强大的CPU和内存;某些微服务是非结构化的数据场景,那么可以使用NoSQL来作为存储。图1-3 展示了不同的微服务可以采用不同的存储方式。


需要注意的是,不限于技术栈,并非可以滥用技术,关键还是要区分不同的场景。例如,在服务器端,我们还是会使用以Java为主的技术,毕竟Java在稳定性和安全性方面比较有优势。而在Linux系统等底层方面的技术,还是推崇使用C语言来实现功能。

可独立部署

由于每个微服务都是独立运行在各自的进程中,这就为独立部署带来了可能。每个微服务部署到独立的主机或虚拟机中,可以有效实现服务间的隔离。

独立部署的另一个优势是,开发者不再需要协调其他服务部署对本服务的影响,从而降低了开发、测试、部署的复杂性,最终可以加快部署速度。UI团队可以采用AB测试,通过快速部署来拥抱变化。微服务架构模式使得持续化部署成为可能。

最近比较火的以Docker为代码的容器技术,让应用的独立部署的成本更加低了。每个应用都可以打包成包含其运行环境的Dockerimage来进行分发,这样就确保了应用程序总是可以使用它在构建映像中所期望的环境来运行,测试和部署比以往任何时候都更简单,因为您的构建将是完全可移植的,并且可以按照任何环境中的设计运行。由于容器是轻量级的,运行的时候并没有虚拟机管理程序的额外负载,这样就可以运行许多应用程序。这些应用程序都依赖于单个内核上的不同库和环境,每个应用程序都不会互相干扰。将应用程序从虚拟机或物理机转移到容器实例,可以获得更多的硬件资源。

有关Docker的内容,也会在后续章节再做深入的探讨。

本篇给大家讲述的是微服务架构的设计原则的内容,喜欢的朋友可以转发关注一下小编!!!

下篇给大家介绍如何设计微服务系统!!感谢大家支持!!加油!