微服务架构设计实践总结和思考:亚博全站APP登录官网,亚博全站官网登录平台,亚博全站最新版app下载
发布时间:2023-10-31 来源:Yabo亚博全站APP登录官网入口 nbsp; 浏览:19652次今天继续谈下在微服务架构设计中的一些实践和思考。对于SOA和微服务,我前面许多文章都举行了详细的论述,今天这篇文章重点还是放在一些架构设计和实践的一些关键点思考上面。微服务架构焦点再次强调,微服务架构焦点是传统单体应用大拆小,同时拆分为小的微服务后相互之间以轻量的API接口举行通信。而这个拆分自己又分了多个方面。
开发团队的拆分代码层的拆分,可独立构建打包数据库的拆分在拆分后为了越发敏捷开发和集成,引入了DevOps和容器云技术。同时思量和SOA,中台思想的融合,思量到API接口的复用性,进一步对单个微服务也举行了前后端分散开发。从单微服务的观点来说,微服务不是指详细的Http API接口服务,而是指拆分后的微服务模块,因此微服务可以明白为:拆分后DB+微服务模块+API接口提供。
微服务架构想想切合当前庞大应用系统分而治之的思想,这个和微服务出来前的组件化开发思路是一致的,只是微服务思想出来后对于拆分的微服务越发高度解耦和独立自治。系统庞大性自己也分为了功效和非功效两个层面。好比一个传统的大业务系统,类似ERP,条约治理等,业务系统足够庞大,需要思量举行分为治之利便后期治理和扩展。其次是非功效性需求导致的庞大性,好比一个业务系统功效并不多,可是文件存储和获取量庞大,那么文件服务就需要单独拆分为微服务。
在很早以前我就强调过,微服务拆分后虽然降低了单个微服务开发实现的难度,可是增加了集成的难度,拆分的越细集成越庞大。因此如果自己不具备上面谈到的庞大性需求,一个业务系统没有须要举行微服务架构拆分和革新。
按划分后的子域拆分数据库在我们实际的项目中,一个原来的单体业务系统,在举行微服务化后,实际拆分为了20个微服务模块,那么按尺度的微服务原则,应该后端也拆分为20个数据库实例。可是这样会导致庞大的集成庞大度和大量漫衍式事务处置惩罚问题。显然,在这种场景下我们引入业务域的观点,即应该按业务域或子域来拆分数据库,可以多个微服务共享一个数据库。
在多个微服务共享一个数据库实例的时候,微服务自己没有做到完全解耦,可是也可以实现代码层解耦。好比某一个需求变换导致微服务A举行了变换,数据库没有变化,那么我们只需要连续集成和公布微服务A模块即可。同时在划分业务域后也越发利便举行团队的划分,即开发团队也根据业务域举行划分,而不是一个开发团队只卖力一个微服务模块。
微服务和微服务API接口注意微服务和微服务模块袒露的API接口是两个观点,这自己也是举行微服务界限划分和微服务管控的两种颗粒度。在主流的微服务开发框架实现中,类似SpringCLoud的实现,对于Eureka,CloudGateway网关等实际都是到微服务这个粒度,也就是服务注册和接入的是微服务模块,而不是一个个独立的API接口服务。
一旦微服务注册接入后,消费端通过注册中心查找到可用的微服务后,那么该微服务通过声明式方式袒露的所有API接口都处于可用状态。在微服务架构开发下,团队实际应该有越发明确的界限,越发粗粒度的接口袒露和交互,而不是简朴的团队A在发现团队B的微服务后,内里所有的API接口都可以随意挪用,这样反而是导致了更多的内部规则外协,也增强了两个微服务模块之间的耦合性。简朴来说,两个微服务之间,不是通过API接口挪用就真正解耦了,而是两个微服务之间仅仅只有少量粗粒度的API接口交付才算真正解耦。
当前实际我们发现的一个关键问题就是微服务也拆分了,开发团队也拆分了,可是多个微服务之间仍然是大量接口随意挪用,这本质仍然是一种紧耦合的架构而难以扩展。如上图,微服务A,D,E划分由差别的开发团队开发,那么他们之间的界限应该控制到详细的API接口粒度,而不是微服务粒度。好比对于微服务E只能消费微服务A袒露的第2个接口,而不能消费接口1。
如果单纯的接纳微服务注册中心方式,实际我们很难真正控制到API接口的粒度。或者说需要我们自己写相应的代码来做细粒度的宁静控制。
面向API接口设计这个是我在前面一直强调的看法,即大型项目或传统的大型单体应用在举行微服务化的时候,一定是架构设计先行。架构设计的关键事情就是:微服务模块拆分,包罗数据库拆分微服务模块袒露的API接口识别界说当做完这两件事情后,单个微服务才气够真正通报给差别的开发团队或小组举行独立的设计开发事情。
同时在微服务开发历程中,需要面向API接口而设计开发,要优先基于前面界说的接口契约来实现需要袒露给外部其他微服务使用的接口,其次再思量内部功效逻辑实现。接口先行的利益就是大家遵循同样的一套接口契约,可以并行开始相关的设计和开发事情,只要接口契约相同,那么后续在多个微服务间集成的时候就应该没有问题。
API接口的治理管控需要提升到相对重要的一个位置。在微服务架构实践中经常看到的情况就是前期架构设计不充实,相关的界限划分不明确,接口界说不明确,导致后期微服务在设计开发历程中连续大量的交互,同时随意的增加和界说新的API接口,这种场景下一定带来后续接口交互和管控治理的杂乱。好比后续在举行微服务变换的时候,我们很难快速的分析出该微服务或API接口变化究竟会影响到哪些其它的微服务模块,微服务和API间的交互依赖关系我们也完全不清楚。这也是我在很早就强调的一个看法,不要期望通事后期的APM或服务链监控来解决微服务自己架构设计阶段的不足,而是应该在前期就按自顶向下思路设计好。
构建独立的领域组合微服务在SOA分层架构内里可以看到,最底层是原子服务,在原子服务上面有组合服务,在组合服务上面另有流程服务。也就是说服务自己也是分层的,虽然越往上走,类似到了组合服务实际的复用度会降低,可是复用效率自己却是加速。
在微服务架构实践内里,原有的单体应用已经拆分为了差别的微服务,每个微服务都可以提供独立的API接口服务能力给前端使用。可是当前端需要的是多个微服务的组合能力的时候,这个能力究竟放在那里?好比前面我们举过一个例子,对于订单提交这个操作,实际需要挪用后端订单中心,预算中心,库存中心多个微服务接谈锋能够完成。在传统方式下这个能力实际是在前端模块完成组合和协同,可是你会发现你开发的应用既有传统的BS端应用,也有APP应用,那么这个组合显然就需要在两个地方重复实现。同时这种组合规则自己也袒露到了前端不合理。
领域组合微服务实际上是一类比力特殊的微服务,即这类微服务自己完成多个微服务API接口的组合编排,完身分布式事务治理和协调,完成组合业务规则的实现和处置惩罚等。这类微服务自己没有自己独立的Owner数据库,也就是这类微服务不直接举行数据库DB层的数据会见和交互,而是直接复用已有的接口服务能力举行组合和组装。在DDD领域驱动设计的架构分层内里,在领域层上有一个独立的应用层,这个应用层即和这类谈到的领域组合微服务对应。而下层的领域层则由多个微服务提供粗粒度的API接口服务能力。
微服务网关和API网关在前面我曾经专门写过微服务网关。API网关一般具备独立的服务注册接入,负载平衡和路由能力,而微服务网关一般则是通过和服务注册中心的集成来实现服务注册发现,负载平衡和路由。简朴来说如果当前微服务A模块有100个接口服务。
在有服务注册发现中心的情况下,微服务A模块部署后会被注册中心自动发现,并加入到可用集群列表中。因此在微服务网关和注册中心集成后,所有的接口服务也自动的注册和接入到了微服务网关中。当用户会见网关提供的服务地址时候整体历程如下图:在这种场景下可以看到实际并不用一个个的API接口在网关上面注册。
可是也无法控制一个微服务哪些详细的接口要接入网关,哪些不接入。同时这里的微服务网关实际上自己也是整体微服务架构体系内里的一个微服务模块,充当了服务消费方的角色。也就是说APP应用无法受整体微服务框架统领,那么对应的依赖包,署理SDK等无法下放到外部应用中,那么这部门内容实际是转移到微服务网关上来资助外部APP应用完成。
而对于相对独立的API网关来说,整体的注册和接入历程是在API网关上面独立完成的,而是是控制到API接口服务粒度举行。固然,你也可以不接纳微服务网关,直接接纳类似Nginx来举行署理和路由转发,可是这个时候需要手工举行微服务节点的设置和心跳检测实现等。一个完整的微服务架构你可以看到。好比有三个独立开发团队举行自己的微服务开发,每个团队自己又接纳前后端分散的开发模式。
那么这个时候实际上每个团队都可以启用自己的注册中心和微服务网关,可是多个团队之间的接口协同则必须控制到API接口这个粒度,即多个团队之间的接口协同接纳API网关举行。这个时候的API网关不属于单个开发团队治理,而属于整个平台层的集成能力。共性基础JAR包依赖在微服务架构拆分后,各个微服务仍然会使用或依赖一些共性基础组件,这些组件自己是独立工程项目,可以独立编译构建。同时各个微服务自己以黑盒Jar包的方式对基础组件包举行依赖。
这类似于在各个微服务内里自己有一个基础的内置SDK包,这个SDK包实现了一些基础共性可复用的方法,或者对一些技术能力举行了统一封装。在这种场景下如果微服务B对Common包提出新需求,Common包分析后仍然是共性需求需要实现,那么Common包会重新编译构建,并举行了版本升级。在这种场景下,实际上微服务A和C两个模块的代码没有做任何修改,那么这个时候A和C是否需要重新举行编译构建?可以很明确的看到这个时候A和C不用举行编译构建,而仅仅需要对微服务B举行编译构建,B在构建的时候会自动获取到最新的Common Jar包。
那么在这个场景下,实际的部署架构下是Common包多个版本共存。为何要如此处置惩罚?简朴来说微服务拆分后,需要做到的就是举行最小化的编译构建和部署,来满足业务需求的变化,能够不重新构建的就不构建,不重新部署的就不部署。只有这样才气够更好的控制住变换规模,也越发容易分析在版本部署后泛起问题。
好比上图,如果Common包升级后,微服务A也重新举行了部署构建,那么这个时候问题究竟出在那里是很难马上做出判断的。固然也存在其它的一些场景:好比对于Common包的版本升级,虽然接口没有变化,可是一个共性方法的实现逻辑泛起了变化,这个时候必须触发三个微服务部署目录下的JAR包举行升级。
而这个场景下自己也有两种方式来做这个事情。其一是三个微服务重新构建来获取新版本Jar包其二是将新的JAR包自动分发到三个微服务部署情况或容器中就当前来说第一种方法很难做,往往都需要对微服务重新举行编译构建,或者重新举行部署。也正是这个原因可以看到,当接纳JAR包或SDK署理包这种方式,最大的一个问题就是版本变化的情况下的升级问题。
面向解耦而设计前面已经谈到,不是你用了Http API接口就是松耦合,如果两个微服务模块之间有大量的API接口交互,那么仍然是一种紧耦合的关系。谈微服务的时候你会发现,一个微服务要乐成正常运行,有大量的底层技术组件或微服务依赖,也有大量的同层的其它微服务模块API接口依赖。如果任何一个依赖的微服务泛起问题,或者数据库泛起问题都市导致微服务无法正常运行。
岂论现在谈缓存,还是谈消息中间件和事件驱动架构,你可以看到都是希望对微服务间举行解耦,对微服务和数据库之间举行解耦。对于焦点的解耦思路实际在前面已经谈到过,即:对于查询,接纳缓存方式举行解耦对于导入或CUD接口,接纳消息中间件解耦实际上面的思路和经常谈到的CQRS下令查询职责分散思路类似,通过CQRS一开始是为了更好的配合读写分散的数据库使用。可是真正CQRS实现解耦的重点仍然是两个。其一是将下令作为事件推送到消息中间件处置惩罚,以制止泛起长周期漫衍式事务。
其次就是启用单独的R读库,可以是数据库,也可以是缓存库,来实现查询功效独立解耦和性能提升。在实际的实践中,差别开发团队之间交互接口最好能够通过消息中间件或缓存举行彻底解耦,以降低相互之间的依赖和影响。好比对于微服务A需要推送数据到微服务B,同时需要从微服务C查询数据。
那么推送数据库到B的接口可以实现为消息接口,先推送数据到消息中间件;而对于数据的查询则可以在获取数据后举行缓存等。变换影响分析在微服务架构实践历程中,由于许多接口是接纳Http API接口方式举行挪用,许多接口修改实际并不会引起编译构建期的错误。因此导致某个微服务接口修改后导致其它微服务模块功效泛起异常的情况。
当泛起问题后,我们才在事后举行修复。对于服务链监控和链路跟踪是一个事后的行为,重点是发现性能问题而不是帮你去分析服务之间的依赖关系。
因此提前梳理清楚微服务间的接口交互和依赖关系是必须的,如上图。通过上图的接口交互矩阵,可以很清楚的看到当某个接口泛起变化的时候,究竟会对哪些微服务模块,哪些功效造成影响,那这些影响点就必须思量配套的变换或者说在提交测试的时候,这些影响到的微服务模块或功效也需要举行测试。
固然如果我们在微服务架构实施历程中,已经形成了完整的基于接口的单元测试和自动化测试,也可以更好的解决和提前发现问题。当你关注点在微服务模块这个粒度的时候,很容易忽略微服务模块间的交互和协同实际需要管控到API接口这个粒度,这是我们在实施微服务架构的时候需要重点关注的一个点。
本文关键词:亚博全站APP登录官网,亚博全站官网登录平台,亚博全站最新版app下载
本文来源:亚博全站APP登录官网,亚博全站官网登录平台,亚博全站最新版app下载-www.chongqiting.cn