一、传统的可扩展性架构之分层架构与SOA架构
1、分层架构
(1)概念
- 分层架构是很常见的架构模式,它也叫 N 层架构,通常情况下,N 至少是 2 层。例如,C/S 架构、B/S 架构。常见的是 3 层架构(例如,MVC、MVP 架构)、4 层架构,5 层架构的比较少见,一般是比较复杂的系统才会达到或者超过 5 层,比如操作系统内核架构。
- 分层架构之所以能够较好地支撑系统扩展,本质在于隔离关注点(separation of concerns),即每个层中的组件只会处理本层的逻辑。分层时要保证层与层之间的依赖是稳定的,才能真正支撑快速扩展。
(2)特点
1、分层架构设计最核心的一点就是需要保证各层之间的差异足够清晰,边界足够明显,让人看到架构图后就能看懂整个架构,这也是分层不能分太多层的原因。
2、分层结构的另外一个特点就是层层传递,也就是说一旦分层确定,整个业务流程是按照层进行依次传递的,不能在层之间进行跳跃
2、SOA架构
(1)背景
SOA 出现 的背景是企业内部的 IT 系统重复建设且效率低下:企业各部门有独立的 IT 系统,比如人力资源系统、财务系统、销售系统,这些系统可能都涉及人员管理,各 IT 系统都需要重复开发人员管理的功能。1、各个独立的 IT 系统可能采购于不同的供应商,实现技术不同,企业自己也不太可能基于这些系统进行重构。2、随着业务的发展,复杂度越来越高,更多的流程和业务需要多个 IT 系统合作完成/3、由于各个独立的 IT 系统没有标准的实现方式,每次开发新的流程和业务,都需要协调大量的 IT 系统,同时定制开发,效率很低。
(2)SOA需要关注的三个点
- 服务:所有业务功能都是一项服务,服务就意味着要对外提供开放的能力,当其他系统需要使用这项功能时,无须定制化开发。
- ESB企业服务总线:因为各个独立的服务是异构的,如果没有统一的标准,则各个异构系统对外提供的接口是各式各样的。SOA 使用 ESB 来屏蔽异构系统对外提供各种不同的接口方式,以此来达到服务间高效的互联互通。
- 松耦合:松耦合的目的是减少各个服务间的依赖和互相影响
(3)SOA总结
- SOA 解决了传统 IT 系统重复建设和扩展效率低的问题,但其本身也引入了更多的复杂性。SOA 最广为人诟病的就是 ESB,ESB 需要实现与各种系统间的协议转换、数据转换、透明的动态路由等功能。当ESB的出现是为了适应当前的架构,企业在应用 SOA 时,各种异构的 IT 系统都已经存在很多年了,完全重写或者按照统一标准进行改造的成本是非常大的,只能通过 ESB 方式去适配已经存在的各种异构系统。
- SOA之所以会出现可以是传统互联网历史遗留问题导致的,从原有复杂的系统进行拆分为服务,然后通过ESB来统一管理,达到服务之间的联通。
(4)思考:为啥SOA不适合互联网?
- 1、首先从互联网和传统企业特点说起。互联网企业的特点就是小,新,快。没有历史包袱,变化快,大部分是从单体演进到分布式,技术栈一脉相承,而到了分布式之后,面对不断的耦合,系统复杂度的陡增,这时一个soa的特例微服务出现了。也就是说需要更加细致的拆分。
- 2、然后从SOA特点说起:soa是集成的思想,是解决服务孤岛打通链条,是无奈之举。esb集中化的管理带来了性能不佳,厚重等问题。也无法快速扩展。不适合互联网的业务特点;
二、微服务基本概念
1、历史
2005 年:Dr. Peter Rodgers 在 Web Services Edge 大会上提出了“Micro-Web-Services”的概念。
2011 年:一个软件架构工作组使用了“microservice”一词来描述一种架构模式。
2012 年:同样是这个架构工作组,正式确定用“microservice”来代表这种架构。
2012 年:ThoughtWorks 的 James Lewis 针对微服务概念在 QCon San Francisco 2012 发表了演讲。
2014 年:James Lewis 和 Martin Fowler 合写了关于微服务的一篇学术性的文章,详细阐述了微服务。推动了微服务的发展
2、微服务和SOA关系
- 对于微服务和SOA,通常看起来二者很相似,并没有什么实质上的不同,因此往往会由下列错误的偏见:
观点一:微服务是 SOA 的实现方式,可以这么说微服务就是更细粒度的 SOA
观点二:微服务是去掉 ESB 后的 SOA。传统 SOA 架构最广为人诟病的就是庞大、复杂、低效的 ESB,因此将 ESB 去掉,改为轻量级的 HTTP 实现,就是微服务。
- 实际上,微服务是一种和 SOA 相似但本质上不同的架构理念,相似就是两者都关注“服务”,都是通过服务的拆分来解决可扩展性问题。本质上不同的地方在于几个核心理念的差异:是否有 ESB、服务的粒度、架构设计的目标等。为什么这么说呢?
1、服务粒度:整体上来说,SOA 的服务粒度要粗一些,而微服务的服务粒度要细一些
2、服务通信:SOA 采用了 ESB 作为服务间通信的关键组件,负责服务定义、服务路由、消息转换、消息传递,总体上是重量级的实现。微服务推荐使用统一的协议和格式,例如,RESTful 协议、RPC 协议,无须 ESB 这样的重量级实现。
3、服务交付:SOA 对服务的交付并没有特殊要求,因为 SOA 更多考虑的是兼容已有的系统;微服务的架构理念要求“快速交付”,相应地要求采取自动化测试、持续集成、自动化部署等敏捷开发相关的最佳实践。
4、应用场景:(1)SOA 更加适合于庞大、复杂、异构的企业级系统,这也是 SOA 诞生的背景。这类系统的典型特征就是很多系统已经发展多年,采用不同的企业级技术,有的是内部开发的,有的是外部购买的,无法完全推倒重来或者进行大规模的优化和重构。因为成本和影响太大,只能采用兼容的方式进行处理,而承担兼容任务的就是 ESB。(传统大型企业)(2)微服务更加适合于快速、轻量级、基于 Web 的互联网系统,这类系统业务变化快,需要快速尝试、快速交付;同时基本都是基于 Web,虽然开发技术可能差异很大(例如,Java、C++、.NET 等),但对外接口基本都是提供 HTTP RESTful 风格的接口,无须考虑在接口层进行类似 SOA 的 ESB 那样的处理。(互联网)
3、到底什么是微服务
- 微服务架构风格是一类将单一应用程序作为由众多小型服务构成之套件加以开发的方式,其中各项服务都拥有自己的进程并利用轻量化机制(通常为HTTP源API)实现通信。这些服务围绕业务功能建立而成,且凭借自动化部署机制实现独立部署。
4、微服务的特点
- (1)应用程序逻辑分为明确定义的职责范围的粒度组件,这些组件相互协调提供解决方案(粒度细、单一职责)
- (2)每一个组件都有一个小的职责领域,可以完全部署,也就是说一个服务可以跨越多个应用程序复用(独立部署和维护)
- (3)服务之间通信基于一些基本的原则,比如服务采用http+json这样的轻量级通信协议,在不同服务之间进行数据交换。这样不同服务可以使用不同的技术栈,互不影响(采用轻量级的通信协议作为通信原则、松耦合)
- (4)拆分为微服务之后,服务的数量变多,因此需要有统一的服务治理平台,来对各个服务进行管理。(服务可治理,可管控)
5、微服务架构的一些通用特性
- 根据MartinFowler的分析,微服务架构有以下的一些通用特性:
1、通过服务实现应用的组件化(按功能拆分、可独立部署和维护)
2、围绕业务能力组织服务(这并不一定,国外是团队前后端搭配,但是中国基本是按不同技术栈划分团队)
3、产品而非项目模式
4、“去中心化”数据和治理
5、基础设施自动化
6、故障处理设计
7、演进式的设计
参考:解析微服务
6、微服务与云
(1)云相关概念
- 基础设施即服务IaaS
- 平台即服务PaaS
- 软件即服务SaaS
(2)为啥微服务需要云(代补充)
- 微服务的一个核心就是每一个服务最终会被打包部署为离散的独立制品,基本上企业部署软件会用以下方式进行,而基于云部署能达到服务的快速上下线操作,伸缩性和灵活性得到很大的提高,同时从成本上也更加可控制。
物理服务器:不易于扩展,不灵活,成本高
虚拟机镜像:虚拟机是云供应商的灵魂,微服务可以打包在虚拟机镜像中,然后开发人员在IaaS私有或者公有云中快速部署和启动服务的多个实例
虚拟容器:是在虚拟机镜像上部署微服务的自然延伸,也就是许多的开发人员不是将微服务直接部署到完整的虚拟机上,而是将docker容器部署到云端,虚拟容器在虚拟机内运行。
- 同时可以利用云厂商提供的各种服务和工具,对于微服务开发是很有利的
7、微服务与devops
- 从运维角度看微服务如何打包、部署和监控是至关重要的。
上一篇文章中主要讲了微服务相关的一些基本概念,以及与传统SOA的区别,这一篇文章主要讲微服务架构设计中需要注意的问题和最佳实践,以及使用spring家族成员构建微服务的一些知识。
三、微服务设计带来的问题及需要注意的地方
1、微服务带来的缺点
(1)运维开销及成本增加
整体应用可能只需部署至一小片应用服务区集群,而微服务架构可能变成需要构建/测试/部署/运行数十个独立的服务,并可能需要支持多种语言和环境。这导致一个整体式系统如果由20个微服务组成,可能需要40~60个进程。
(2)必须有坚实的DevOps开发运维一体化技能
开发人员需要熟知运维与投产环境,开发人员也需要掌握必要的数据存储技术如NoSQL,具有较强DevOps技能的人员比较稀缺,会带来招聘人才方面的挑战。
(3)隐式接口及接口匹配问题,带来发布风险
把系统分为多个协作组件后会产生新的接口,这意味着简单的交叉变化可能需要改变许多组件,并需协调一起发布。在实际环境中,一个新品发布可能被迫同时发布大量服务,由于集成点的大量增加,微服务架构会有更高的发布风险。
(4)代码重复
某些底层功能需要被多个服务所用,为了避免将“同步耦合引入到系统中”,有时需要向不同服务添加一些代码,这就会导致代码重复。
(5)分布式系统的复杂性
作为一种分布式系统,微服务引入了复杂性和其他若干问题,例如网络延迟、容错性、消息序列化、不可靠的网络、异步机制、版本化、差异化的工作负载等,开发人员需要考虑以上的分布式系统问题。
(6)可测性的挑战
在动态环境下服务间的交互会产生非常微妙的行为,难以可视化及全面测试。经典微服务往往不太重视测试,更多的是通过监控发现生产环境的异常,进而快速回滚或采取其他必要的行动。但对于特别在意风险规避监管或投产环境错误会产生显著影响的场景下需要特别注意。
2、微服务架构设计过程中需要注意的点
(1)服务划分过细,服务间关系复杂
(2)服务数量太多,团队效率急剧下降
(3)调用链太长,性能下降
(4)调用链太长,问题定位困难
(5)没有自动化支撑,无法快速交付(自动化测试、自动化部署、自动化监控等)
(6)没有服务治理,微服务数量多了后管理混乱(服务路由、服务故障隔离、服务注册与发现等等)
(7)其他
- 总结微服务设计中需要避免如下几种情况。1、微服务拆分过细,过分强调“small2、微服务基础设施不健全,忽略了“automated”3、微服务并不轻量级,规模大了后,“lightweight”不再适应。
四、微服务架构最佳实践
1、方法篇
(1)服务粒度的划分
服务粒度的划分是伴随着架构演进进行的,需要考虑当前的人力、物力等来有效的统筹,在项目的初期可以把服务的粒度设计大一点,随着项目的不断壮大,团队的规模不断变大,可以对现有的粗粒度服务进行有效的拆分,逐步的向细粒度服务发展。
(2)拆分
在进行服务拆分的时候是有张可寻的,需要根据自己的项目进行设计,并不能一味的按功能、按大小、按人力等去拆分。基本的拆分可以按如下的几种方式进行。
1、基于业务逻辑进行拆分。这是最常见的一种拆分方式,将系统中的业务模块按照职责范围识别出来,每个单独的业务模块拆分为一个独立的服务。基于业务逻辑拆分虽然看起来很直观,但在实践过程中最常见的一个问题就是团队成员对于“职责范围”的理解差异很大,因此根据业务拆分需要权衡当前项目组的情况。
2、基于可扩展拆分。将系统中的业务模块按照稳定性排序,将已经成熟和改动不大的服务拆分为稳定服务,将经常变化和迭代的服务拆分为变动服务。稳定的服务粒度可以粗一些,即使逻辑上没有强关联的服务,也可以放在同一个子系统中,例如将“日志服务”和“升级服务”放在同一个子系统中;不稳定的服务粒度可以细一些,但也不要太细,始终记住要控制服务的总数量。这样拆分主要是为了提升项目快速迭代的效率,避免在开发的时候,不小心影响了已有的成熟功能导致线上问题。
3、基于可靠性拆分。将系统中的业务模块按照优先级排序,将可靠性要求高的核心服务和可靠性要求低的非核心服务拆分开来,然后重点保证核心服务的高可用。这样拆分带来下面几个好处:(避免非核心服务故障影响核心服务、核心服务高可用方案可以更简单、能够降低高可用成本)
4、基于性能拆分。基于性能拆分和基于可靠性拆分类似,将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其他服务。常见的拆分方式和具体的性能瓶颈有关,可以拆分 Web 服务、数据库、缓存等。
2、基础设施篇
大部分人主要关注的是微服务的“small”和“lightweight”特性,但实际上真正决定微服务成败的,恰恰是那个被大部分人都忽略的“automated”。也就是说基础设施在微服务中占据的主导作用。如果“automated”相关的基础设施不健全,那微服务就是焦油坑,让研发、测试、运维陷入微服务的各种陷阱中。
上图是微服务架构中涉及的基础设施,可以看出建设完善的微服务基础设施是一项庞大的工程,但是并不是中小企业就不能玩转微服务。第一个原因是已经有开源的微服务基础设施全家桶了,例如大名鼎鼎的 Spring Cloud 项目,涵盖了服务发现、服务路由、网关、配置中心等功能;第二个原因是如果微服务的数量并不是很多的话,并不是每个基础设施都是必须的。通常情况下,可以按照下列的优先级来搭建微服务的基础设施。
- 服务发现、服务路由、服务容错:这是最基本的微服务基础设施。
- 接口框架、API 网关:主要是为了提升开发效率,接口框架是提升内部服务的开发效率,API 网关是为了提升与外部服务对接的效率。
- 自动化部署、自动化测试、配置中心:主要是为了提升测试和运维效率。
- 服务监控、服务跟踪、服务安全:主要是为了进一步提升运维效率。
五、使用SpringBoot和SpringCloud构建微服务
- 在基于java的应用程序构建中,spring已经成为事实上的标准开发框架,spring框架迷人的地方就是能够与时俱进的进行自我改造。随着发展,spring团队不仅开发出了单体应用程序模型,还转向了高度分布式的模型,使服务能够轻松的部署到云端,典型代表就是springboot和springcloud。
- springboot是对spring框架理念的重新思考,虽然springboot包含了spring的核心特性,但是它剥离了spring中的许多企业特性,而是提供一个基于java的、面向REST的微服务框架,只是需要简单的注解,java开发者就能快速构建一个可打包和部署的REST微服务。
- springcloud框架使实施和部署微服务到私有云或者公有云变得更加简单,springcloud在一个公共框架之下封装了许多流行的云管理微服务框架,并且让这些技术的使用和部署像为代码添加注解一样简单。