微服务架构思考
微服务架构思考
拆大为小,分而治之。数据缓存,异步消息。
微服务架构核心是传统单体应用大拆小,同时拆分为小的微服务后相互之间以轻量的API接口进行通信。而这个拆分本身又分了多个方面。
- 开发团队的拆分
- 代码层的拆分,可独立构建打包
- 数据库的拆分
微服务可以理解为:拆分后DB+微服务模块+API接口提供。
如何拆分数据库
在我们实际的项目中,一个原来的单体业务系统,在进行微服务化后,实际拆分为了20个微服务模块,那么按标准的微服务原则,应该后端也拆分为20个数据库实例。但是这样会导致巨大的集成复杂度和大量分布式事务处理问题。
显然,在这种场景下我们引入业务域的概念,即应该按业务域或子域来拆分数据库,可以多个微服务共享一个数据库。在多个微服务共享一个数据库实例的时候,微服务本身没有做到完全解耦,但是也可以实现代码层解耦。
比如某一个需求变更导致微服务A进行了变更,数据库没有变化,那么我们只需要持续集成和发布微服务A模块即可。
同时在划分业务域后也更加方便进行团队的划分,即开发团队也按照业务域进行划分,而不是一个开发团队只负责一个微服务模块。
API粗粒度接口
在微服务架构开发下,团队实际应该有更加明确的边界,更加粗粒度的接口暴露和交互,而不是简单的团队A在发现团队B的微服务后,里面所有的API接口都可以随意调用,这样反而是导致了更多的内部规则外协,也加强了两个微服务模块之间的耦合性。
简单来说,两个微服务之间,不是通过API接口调用就真正解耦了,而是两个微服务之间仅仅只有少量粗粒度的API接口交付才算真正解耦。
面向API接口设计
微服务模块拆分,包括数据库拆分。当做完这两件事情后,单个微服务才能够真正传递给不同的开发团队或小组进行独立的设计开发工作。同时在微服务开发过程中,需要面向API接口而设计开发,要优先基于前面定义的接口契约来实现需要暴露给外部其他微服务使用的接口,其次再考虑内部功能逻辑实现。
接口先行的好处就是大家遵循同样的一套接口契约,可以并行开始相关的设计和开发工作,只要接口契约相同,那么后续在多个微服务间集成的时候就应该没有问题。
构建独立的领域组合微服务
在SOA分层架构里面可以看到,最底层是原子服务,在原子服务上面有组合服务,在组合服务上面还有流程服务。也就是说服务本身也是分层的,虽然越往上走,类似到了组合服务实际的复用度会降低,但是复用效率本身却是加快。
在微服务架构实践里面,原有的单体应用已经拆分为了不同的微服务,每个微服务都可以提供独立的API接口服务能力给前端使用。
领域组合微服务实际上是一类比较特殊的微服务,即这类微服务本身完成多个微服务API接口的组合编排,完成分布式事务管理和协调,完成组合业务规则的实现和处理等。
这类微服务本身没有自己独立的Owner数据库,也就是这类微服务不直接进行数据库DB层的数据访问和交互,而是直接复用已有的接口服务能力进行组合和组装。
在DDD领域驱动设计的架构分层里面,在领域层上有一个独立的应用层,这个应用层即和这类谈到的领域组合微服务对应。而下层的领域层则由多个微服务提供粗粒度的API接口服务能力。
面向解耦而设计
不论现在谈缓存,还是谈消息中间件和事件驱动架构,你可以看到都是希望对微服务间进行解耦,对微服务和数据库之间进行解耦。
对于核心的解耦思路实际在前面已经谈到过,即:
- 对于查询,采用缓存方式进行解耦
- 对于导入或CUD接口,采用消息中间件解耦
实际上面的思路和经常谈到的CQRS命令查询职责分离思路类似,通过CQRS一开始是为了更好的配合读写分离的数据库使用。但是真正CQRS实现解耦的重点仍然是两个。
其一是将命令作为事件推送到消息中间件处理,以避免出现长周期分布式事务。其次就是启用单独的R读库,可以是数据库,也可以是缓存库,来实现查询功能独立解耦和性能提升。
在实际的实践中,不同开发团队之间交互接口最好能够通过消息中间件或缓存进行彻底解耦,以降低相互之间的依赖和影响。
比如对于微服务A需要推送数据到微服务B,同时需要从微服务C查询数据。那么推送数据库到B的接口可以实现为消息接口,先推送数据到消息中间件;而对于数据的查询则可以在获取数据后进行缓存等。
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/14626569.html