⼀⽂带你搞懂微服务架构深度解析:微服务的采⽤前提,技术
与理念
技术与理念
微服务的概念还在快速发展的过程中,它不仅给我们提供了分布式下细粒度服务设计、构建、交付、运维的⽅法,同时整合了过去⼏年⾏业的先进技术和最佳实践。
⾯向服务
⼤部分企业选择微服务架构是业务驱动的。对于基于传统J2EE技术栈的Web项⽬⽽⾔,早期单体架构就是所谓的“⼀个War包打天下”,将应⽤程序的所有功能都打包成⼀个独⽴的War包,部署在Tomcat的指定⽬录下就可以顺利运⾏。然⽽,软件项⽬是⼀个不断迭代和变化的过程,业务模块的增加、功能的扩展、⼈员的更迭、需求的变动最终都需要修改代码来实现。于是代码跟随版本的不断升级⽽逐渐膨胀变得难以维护。单体架构的灵活性、可扩展性、可运维性都明显下降,开发⼈员效率降低、系统稳定性变差、局部⼩问题导致“牵⼀发⽽动全⾝”。
在这种情况下,单体架构为了保证程序内部的⾼内聚、低耦合,引⼊了分层的架构模式。分层架构在某种程度上解决了不同类型代码的逻辑耦合问题,模块之间有了更加清晰的职责划分,降低了单体架构的
整体复杂度。⽽分层架构的问题是没有聚焦当前业务逻辑,以技术为导向的架构形态很难做到服务的复⽤,业务模块⽆法独⽴部署和演进。
微服务的理念与SOA服务架构是⼀脉相承的,微服务架构同样强调⾯向服务,将⼀个⼤的“问题空间”通过领域建模拆解分为实体之间的关系和⾏为,使⽤限界上下⽂(Bounded Context)将实现细节封装起来,让服务可以独⽴伸缩,每个服务都有明确的边界。
在⾯向业务构建微服务时,我们不应该把主要的关注点放在是采⽤ Tomcat 还 是 Jetty 应 ⽤ 容 器 上 , 也 不 应 该 放 在 Spring Cloud 、Docker、RPC这些技术概念或框架上。微服务架构⾸先要考虑的是解决业务的问题。在开始微服务架构转型之前,请先理解业务,洞察业务边界、职责划分,让团队专注于实现某个特定的应⽤服务。微服务需要根据⼀定的软件设计原则来实现⾯向服务的架构模式,本⽂在微服务构建章节会深⼊讲解领域驱动设计如何帮助我们对系统进⾏合理的服务划分,如何拆解、聚合以实现服务的开发和复⽤。另外,⾯向服务的系统的服务边界划分需要我们格外注意,因为错误的服务领域划分将会使服务陷⼊⼤量的远程调⽤和分布式事务中,在这种情况下,微服务给整个系统带来的不是便利⽽是⿇烦。
底座技术
从效率的⾓度出发,微服务架构需要配套的技术栈和技术底座⽀撑。⽬前,很多⼀线互联⽹公司已经
成功基于底座技术实现了微服务架构的落地和实践。
技术选型是落地微服务架构的关键环节,公司在落地微服务架构的过程中,不仅仅要关注技术本⾝,更重要的是结合⾃⼰公司的技术现状和⼈员技术背景,根据已有的技术栈来进⾏微服务架构的落地和实践。
从技术选型的⾓度出发,我们需要根据⼀定的优先级来考虑:需求满⾜度、社区活跃度、技术掌控能⼒。
● “需求满⾜度”是最重要的因素,因为技术和架构最根本的动机还是满⾜业务的需求,如果⼀项先进的技术没有满⾜⽤户的需求,则这项技术将失去发展的动⼒。
● “社区的活跃度”是⾮常重要的参考,因为社区的活跃度代表了这项技术被⼴⼤开发者接受的程度和这项技术的⼴泛度和⽣命⼒。对于技术薄弱的公司,最好采⽤在⼀线互联⽹公司落地并且在社区内拥有良好⼝碑的开源产品。因为这些技术已经在⼤企业中经过了⽣产环境的验证,并且有良好的社区⽣态,可以得到更多的技术⽀持。当然,有实⼒的公司会选择通过⾃研的⽅式落地微服务架构,⽽对于⼩规模团队,还是建议采⽤社区的技术框架落地微服务架构,⼀⽅⾯可以不⽤从头开始,另⼀⽅⾯,也会降低公司的整体学习成本。springboot架构图
● 同时,需要考虑公司⼈员的技术掌控能⼒。例如,如果⼀个框架使⽤C语⾔实现了微服务架构,虽然在性能上有优势,但整个团队没有懂C语⾔的开发者,那么就需要重新考虑是否有其他的替代技术⽅案。
基于Spring社区的影响⼒,⽬前可以认为Spring Boot是构建Java微服务架构的事实标准;另外,Dubbo是阿⾥多年的⽣产级分布式微服务实践的技术结晶,Dubbo本质上是⼀套基于Java的RPC框架,服务治理能⼒⾮常强,在国内技术社区中具有很⼤的影响⼒。还有ApacheServiceComb等国内外知名微服务框架,这⾥就不再赘述。
架构技术
单体架构被拆分为微服务后,需要解决众多服务的治理及复杂度管控问题。微服务存在领域模型建设、服务边界划分、服务与服务之间的依赖、服务交互集成、独⽴数据管理等问题,针对这些,我们需要优化我们的架构设计理念和设计⽅法。
领域驱动设计
Eric Evans在《领域驱动设计》⼀书中对不同公司的业务应⽤程序中遇到的复杂问题进⾏了总结,帮助我们在现实世界中进⾏建模。
他为领域驱动设计提出了⼤量的最佳实践和经验技巧:
● 领域驱动设计⽅法有利于软件开发团队与业务部门或领域专家密切合作,使开发⼈员与业务⼈员达成共识。
● 技术⼈员和业务专家应该⾸先进⾏领域建模,到有界的上下⽂和相关的核⼼域,以及普遍存在的语⾔、⼦域、上下⽂映射,⽤于简化软件项⽬的复杂度,使得设计思路能够更加清晰、设计过程更加规范。
对于微服务架构⽽⾔,它和领域驱动设计同样关注业务。领域驱动设计理念聚焦于领域建模、实体、边界划分、界限上下⽂。领域驱动设计⾮常适合从业务上去划分微服务的边界,定义服务对外暴露的接⼝。每⼀个微服务都应该是⼀个可以独⽴开发、部署、运⾏的⾃治主体。可以说,领域驱动设计是指导微服务架构设计、解耦业务、服务拆分、服务构建的关键原则。
前后端分离技术
微服务倡导专业分⼯,每个组件都专注于各⾃的业务领域。⽽⼤部分软件,尤其是⾯向企业领域的系统基本都是由前端和后端服务组成的。将前后端分离作为切⼊点,我们可以轻松地开启微服务化改造之旅。下⾯是微服务架构进⾏前后端职责划分的主要规则:
● 技能分离,前后端可以使⽤不同的特定语⾔或框架来实现最佳的微服务实践。
● 职责分离,前端主要负责和⽤户的交互逻辑,后端主要负责业务逻辑和资源的管理。
● 部署分离,前端和后端可以做到独⽴发布,不存在发布过程的耦合,前端和后端可以根据约定的API进⾏版本迭代和独⽴演进。
前后端分离架构有利于将微服务在技术层⾯上解耦,后端微服务可以专注于实现对后端服务和资源的管理,⽽不⽤再关注与⽤户交互的逻辑验证等问题。
前后端分离有利于微服务中的各组件的演进和组合,微服务架构细粒度的服务可以让不同前端共享不同后端,通过“搭积⽊”的⽅式实现服务的复⽤和独⽴的演进,如下图所⽰。
事件驱动技术
在单体架构下,系统的复杂性在于如何做好模块之间的解耦,因为模块依然存在于同⼀个进程中,实现进程内的并发处理和多线程模型的管理是单体架构的主要⼯作。所以单体架构的瓶颈往往是CPU,不适合⽹络I/O密集型的计算处理场景。⽽在微服务架构下,因为细粒度的服务之间的交互主要通过分布式⽹络进⾏,⽽事件驱动架构为微服务提供了更多的跨⽹络集成优势。
● 基于事件的体系结构是异步的,不存在⽹络阻塞。在提供服务之前,我们必须考虑⽹络的局限性。选择REST同步调⽤⽅式存在服务调⽤依赖问题,会产⽣级联消息雪崩效应,⽽选择事件机制我们不⽤担⼼同步调⽤的问题。
● 基于消息队列的异步消息处理机制。相⽐请求/响应模式的服务集成⽅式,采⽤Broker代理的服务集成⽅式可实现服务之间的解耦,同时可以提⾼服务的性能、可靠性、可扩展性。
然⽽,事件驱动框架也会在消息⼀致性、消息的监控和传输上给系统带来额外的技术复杂性。
● “协同”优先“编排”原则。事件编排机制会由“中⼼⼤脑”
来领导并驱动整个流程,这个⼤脑就像交响乐队中的指挥;事件协同机制会预先说明清楚系统中各个部件的职责,⽽把具体怎么实现留给各个部件。总的来说,事件编排机制的缺点是明显的,中⼼控制
点承担了太多职责,它会成为⽹状结构的中⼼枢纽。⽽事件协同机制不仅可以降低系统的耦合性,还可以让我们以更加灵活的⽅式修改现有系统。
● CQRS(Command and Query Responsibly Separate,命令查询职责分离),是介于脚本驱动和领取驱动之间的⼀种服务建模与数据交互模式,是事件驱动领域中被⼴泛使⽤的⼀个概念,通过CQRS可以解决数据读写交叉问题,并能有效降低业务逻辑的复杂性。
服务监控与治理
在单体架构时代,因为所有服务都集中在少数⼏个系统中,系统之间的相互调⽤关系相对简单,在出现故障时,可以将问题根源锁定在有限的系统范围内并定位问题。⽽在微服务架构下,众多微服务实例之间有频繁的分布式跨⽹络协作、相互远程调⽤,这时如果没有⼀整套服务治理⽅法,帮助我们保证SLA(Service-Level Agreement,服务等级协议)、增强服务治理⽔平、提升微服务的治理与运维效率,那么微服务的转型之路将举步维艰。
技术团队关注的焦点往往是架构的实现和业务建模,容易忽略微服务架构带来的⼀系列负⾯影响,通过微服务监控与治理可以全⽅位地掌控当前服务的运⾏状态和资源利⽤情况,可以说,服务治理与监控既是微服务架构在平台层⾯的核⼼⼯作,也是微服务应⽤“长治久安”的前提。通过微服务治理能⼒的提升,可以提供对业务应⽤的快速响应能⼒、保证业务的健康稳定及持续演进;在技术上,可以帮助
微服务的开发和运维⼈员实时地掌握微服务的运⾏状态,以及进⾏问题定位和故障恢复。
在服务治理的技术选型上,Spring Cloud提供了服务治理的⼀站式解决⽅案。同时,微服务框架结合众多技术组件可以提供Metrics指标监控、⽇志监控、调⽤链等信息监控、健康检查和告警通知等功能。Metrics监控主要依赖于时间序列数据库,⽬前较成熟的产品有Prometheus 和 OpenTSDB; 我 们 可 以 采 ⽤ ELK ( Elasticsearch 、Logstash、Kibana三个技术框架缩写)技术栈实现⽇志的归集、存储、搜索和可视化报表查看等;可以采⽤Spring Cloud Sleuth⽇志收集⼯具包,结合Zipkin和HTrace,作为Spring Cloud的⼀种分布式追踪解决⽅案。
容器和⾃动化技术
容器和⾃动化技术可以说是微服务规模化发展需要解决的⾸要问题。基于容器的部署和交付⽆论在软件开发领域,还是运维相关领域,都带来了巨⼤的技术颠覆。通过⾃动化交付部署可以将开发与运维环节打通。交付物的标准化使得我们可以“标准化”地交付应⽤及它所依赖的运⾏环境。Docker容器⼀次构建、多次交付的特性可以使微服务具备了更好的可移植性、可复⽤性。
很多⼈把容器化和微服务架构混为⼀谈,认为⾃⼰的服务部署到了容器后,系统就是⼀个微服务架构了。其实⼆者存在本质上的差异。可以说,⼀个巨⽯型单体架构即使部署到了容器上,依然⽆法改变它架构上的“拙劣”。
⽬前容器技术仍然是微服务架构最佳的运⾏时环境和平台,也很好地⽀撑了微服务架构去中⼼化、细粒度、容错、伸缩的特性。如下图所⽰,是虚拟机与容器不同的隔离机制。
虚拟机
容器
使⽤传统虚拟机的应⽤存在如下运维弊端:
● 部署⾮常慢、成本⾮常⾼、资源浪费。
● 难以迁移和扩展。
● 服务与硬件⼚商提供的特性绑定。
使⽤容器对微服务架构进⾏⾃动化运维的优势:
● 容器的资源开销更⼩,Docker本⾝共享操作系统内核,容器可以节省更多物理机资源。
● 在开发和运维之间搭建了⼀座桥梁,是实现DevOps的最佳⽅案。
● 容器可以对软件和其依赖的标准镜像格式打包,保证应⽤在不同运⾏环境下的统⼀交付,解决环境差异问题和⼤规模的交付部署问题。
● 容器本质上相当于⼀个进程,每个容器都可以看作⼀个不同的微服务进程,因此可以独⽴升级,与底层共享操作系统,性能更加优良,系统负载更低,在同等硬件资源条件下可以运⾏更多的应⽤实例,更充分地利⽤系统资源。
● 在没有适合的⼯具和⾃动化运维的情况下,使⽤微服务架构会导致灾难。⽬前基于容器技术和Kubernetes技术的平台已经成为微服务交付和管理的最佳平台。
云原⽣12要素
Gartner定期发布的技术成熟度曲线可以帮助我们⽅便地评估技术的成熟度,同时帮助我们制定战略,即采⽤怎样的技术⼯具。Gartner最新发布的技术影响⼒和普及模式与成熟度分析说明,微服务架构已
经在中国全⾯进⼊成熟落地阶段,从全球来讲,很多知名IT企业和公司,像亚马逊、Netflix、阿⾥巴巴,已经采⽤微服务架构重塑了⾃⼰的核⼼业务系统。当前,很多公司为了节省成本、减少对基础硬件设施的投⼊,纷纷选择采⽤公有云或者私有云的⽅式管理公司的应⽤服务和基础设施。
云原⽣12要素(如下图所⽰)是基于云的架构设计和开发模式需要具备的⼀套全新的理念,也是云原⽣应⽤开发的最佳实践原则。
● 要素1:基准代码
基准代码和应⽤之间总是保持⼀⼀对应的关系:⼀旦有多个基准代码,就不能称为⼀个应⽤,⽽是⼀个分布式系统。分布式系统中的每⼀个组件都是⼀个应⽤,每⼀个应⽤都可以分别使⽤云原⽣12要素进⾏开发。
● 要素2:依赖显式声明依赖关系,应⽤程序不会隐式依赖系统级的类库。要通过依赖清单,确切地声明所有依赖项。此外,在运⾏过程中通过依赖隔离⼯具来确保程序不会调⽤系统中存在但清单中未声明的依赖项。这⼀做法会统⼀应⽤到⽣产和开发环境。像Java语⾔使⽤的Maven打包软件或者Cradle都可以显式声明依赖。
● 要素3:配置
通常应⽤的配置在不同部署环境(预发布、⽣产环境、开发环境等)中会有很⼤差异。Factor推荐将应⽤的配置存储于环境变量中。我们可以⾮常⽅便地在不同的部署环境中修改环境变量,却不动⼀⾏代码。
● 要素4:后端服务
这⾥的后端服务指的是应⽤运⾏所依赖的各种服务,例如数据库、消息代理、缓存系统等,对于云原
⽣应⽤来说,往往还会有⽇志收集服务、对象存储服务及各种通过API访问的服务,可以把这些服务作为外部的、通过⽹络调⽤的资源。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论