⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7258284459580801082 「码拉松」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

引言

天下大势,分久必合,合久必分,这是历史上无数次战争和政治斗争所证明的真理。而今,这一理论同样适用于当今的技术发展,尤其是在微服务的架构设计中。

随着企业的不断发展和壮大,原来单一的系统架构逐渐无法满足日益增长的需求。为了更好地应对这些变化,越来越多的企业开始采用微服务架构。微服务架构的核心思想是将整个系统分解成多个独立的服务,每个服务都可以独立部署、扩展和维护。

这种架构设计的优势在于可以更好地满足业务需求的变化,提高了系统的灵活性和可维护性。然而,随着企业不断扩大规模和增加服务数量,系统的复杂度也随之增加。因此,微服务的架构设计也需要随之进行分分合合,以适应系统不断变化的需求。

在微服务架构设计中,分是指将整个系统分解成多个独立的服务,每个服务都可以独立部署、扩展和维护。这种设计方式可以提高系统的灵活性和可维护性,降低了整个系统的复杂度。而合则是指将多个独立的服务组合成一个更大的系统,形成一个更完整的功能。

总的来说,微服务架构的设计需要在分分合合之间取得平衡。只有在合适的时机进行分解和组合,才能够实现系统的灵活性和可维护性。而对于设计者来说,需要充分考虑服务之间的通信、复用和依赖关系等因素,以确保系统的高可用性和可扩展性。

背景介绍

根据微服务的定义,微服务建议将单个应用程序划分为一组小型服务。然而,对于“小”的定义是由使用者决定的,因此这个服务是否应该拆分,拆分成什么样,在某些情况下可能存在分歧。

因此,在这样一个背景之下,如果拆分不当可能会出现以下问题:

  1. 沟通和协调问题:各个服务之间的沟通和协调可能会变得更加复杂,需要确保各个服务之间的交互能够顺利进行。
  2. 服务依赖关系问题:服务之间的依赖关系可能会变得更加复杂,需要确保各个服务之间的依赖关系清晰明确,避免出现冲突和不一致的情况。
  3. 系统性能问题:由于微服务之间通信需要通过网络,因此可能存在较长的调用链路,这会影响服务的响应速度和吞吐量。
  4. 部署和维护问题:部署和维护可能会变得更加复杂,需要确保各个服务能够顺利部署和维护。
  5. 集成问题:微服务之间的集成问题可能会导致集成测试和部署困难,从而增加了开发和维护的成本。
  6. 故障传播问题:当一个微服务发生故障时,可能会导致整个应用程序的不可用,这会影响用户的体验和业务的稳定性。

调用链路分析

接下来,我们将调用链路作为一个问题,探讨不当的服务划分所带来的具体影响。

调用链路增长趋势:理论上如果你有N个微服务,那么你的调用链路就有N*(N-1)条。

比如,当有3个微服务,可能会存在6条链路

当有5个微服务,存在的链路将增长至20条

影响一:重复调用

C和D都被多次调用,流量被额外放大,末尾服务压力巨大。

影响二:循环依赖

关系理不清,问题定位困难,互相消耗,最终也不知道究竟是谁影响了谁?

影响三:链路混乱

链路又长又臭,关系理不清,问题定位困难,迭代效率低。

治理思路

重复调用

能力下层,方法封装

在需求迭代过程中,重复调用可能并非一开始就存在,而是因为多个开发人员在代码逻辑和上下文理解上存在不足,导致出现了重复调用的情况。针对这一问题,我们可以采取链路追踪的方法来发现重复调用,并结合业务代码的上下文逻辑,将重复调用的逻辑下沉并内聚,以避免重复的调用造成的性能问题。另外,为了避免重复调用造成的问题,可以在编写代码时尽量避免出现多次调用同一个方法或函数的情况。可以采用缓存技术或者封装好的类库等方式来解决这一问题,避免因为调用不同实现而产生的重复调用。此外,还可以通过设计良好的模块化架构来减少重复调用的发生。例如,将相关的方法和函数封装到同一个模块中,可以有效避免重复调用的问题。

在实际的开发过程中,重复调用的问题可能并不总是显而易见的,需要我们有耐心地去查找和分析。如果在发现问题后能够及时进行修复,可以避免不必要的性能问题和代码混乱的情况,提高代码的可维护性和可读性。

循环依赖

划分层级,确认关系

在解决循环依赖问题时,我们需要重新审视应用的分层结构以及依赖关系划分。因为循环依赖通常源于业务场景中的问题,我们需要仔细定义各应用之间的职责范围和依赖关系,以便重新划分应用之间的层级结构,消除循环依赖问题。

链路混乱

领域识别,定义职责

为了解决链路混乱的问题,我们需要进行应用架构设计的优化。在设计应用架构时,我们需要考虑多个团队之间的合作和沟通,以及各自领域内的业务职责定义。如果团队过大,那么就有可能导致应用的架构设计出现混乱。

我们可以借鉴“两个披萨原则”来衡量团队大小。如果两个披萨不足以喂饱一个项目团队,那么这个团队可能就显得太大了。因此,在应用架构设计过程中,我们需要充分理解与识别业务的核心问题,根据这些问题划分出相关领域,并确认领域职责以及边界。在领域与领域之间的依赖关系上,我们需要遵循“上层应用可以依赖任意一层下层应用,但下层应用不能依赖上层应用”的原则。

应用领域划分清楚后,我们还需要实现各应用领域内的垂直域,按照应用领域的划分思想来实现,避免层级太多之后,同样容易出现链路混乱,依赖过多的现象。这样就能够有效地提高应用的架构设计质量,减少链路混乱的问题。

服务的拆分与合并

定期审视,做好规划

永恒不变的是变化,这个真理同样适用于业务的发展与变化。由于环境的不断变化,组织结构、研发团队等方面也可能随之发生改变。因此,有时候我们不能只是将服务的划分看作是一个是非问题,而应该在现在的环境以及未来的规划中,重新审视服务的划分。我们需要思考:在当前环境下,是否需要对服务进行重新划分,划分是否过于细致,或者是否需要合并或拆分。只有这样,我们才能更好地适应业务的发展和变化。

总结

我认为在进行微服务改造之前,需要先了解自身情况,判断是否需要进行微服务拆分。微服务拆分是一个逐步的过程,需要有架构演进的把控能力,并逐步完善和调整实施细节。此外,应该积极听取组织内外的经验意见,因为经验意见可能会触发更多的思考,有效避免微服务拆分中的“深坑”。

文章目录
  1. 1. 引言
  2. 2. 背景介绍
  3. 3. 调用链路分析
  4. 4. 治理思路
    1. 4.0.1. 重复调用
    2. 4.0.2. 循环依赖
    3. 4.0.3. 链路混乱
    4. 4.0.4. 服务的拆分与合并
  • 5. 总结