简短解析浅述SpringBoot六边形架构案例
Posted Java_LingFeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简短解析浅述SpringBoot六边形架构案例相关的知识,希望对你有一定的参考价值。
六边形架构是一种用于设计软件应用程序的架构模式。近年来,它的受欢迎程度有所增加,因为它是传统分层架构的替代品。
分层架构有什么问题? 这种架构模式应用 SoC(关注点分离)原则将我们的组件分解为层,每一层都有不同的职责。通常,有 3 层:
-
表示层,其中包含用户界面。
-
业务层或领域层,包含业务逻辑。
-
持久层,处理数据库操作。
在应用这种架构模式时,我们面临着层与层之间的依赖关系,即每一层都依赖于紧接其下的层。该模型未能表明我们可以与多个数据库交互或根本不与任何数据库交互。此外,表示层没有考虑到用户与我们的应用程序交互的方式可能不止一种。
六边形架构如何克服分层架构的弊端? 该模型将所有业务逻辑置于应用程序的核心,抽象出任何类型的外部依赖。这种隔离使得逻辑更容易测试和维护。 应用程序现在拥有一个或多个处理用户请求的输入适配器,而不是表示层。 类似地,现在我们有一个或多个输出适配器来调用外部应用程序或服务,而不是持久层,例如 Amazon S3 中的文件存储、SendGrid 等电子邮件服务,或者更常见的是数据库。
业务核心有一个或多个端口。端口定义了一组操作,允许核心与适配器进行交互,从而与应用程序外部的内容进行交互。正如我们有两种类型的适配器,输入和输出,有一个输入端口和一个输出端口。输入端口是内核公开的供外部应用程序访问的 API,而输出端口是允许内核使用外部服务的接口。 输入适配器通过调用输入端口来处理来自外部世界的请求。这方面的一个例子是实现 REST API 或 gRPC 服务器的 Spring 控制器。 输出适配器实现了一个输出端口,该端口通过调用外部应用程序或服务来处理来自业务核心的请求。一些示例是执行数据库操作的 DAO(数据访问对象)类,或使用电子邮件服务的 Spring 组件。 到目前为止,我们已经看到了与六边形架构相关的概念。现在,让我们将理论付诸实践,并使用 Kotlin 构建一个 Spring 应用程序。 首先,我个人喜欢将项目分为三个主要包:
-
“core”包,包含与核心业务相关的组件。
-
“ ports ”包,包含将业务核心与外界通信的输入和输出组件。
-
“ config ” 包,用于启动应用程序和处理其内部行为所需的所有配置。
构建Core 放置我们的Article实体。请注意,它使用普通的 Kotlin(或 Java),但完美地代表了业务实体。
package com.github.manerajona.blog.core import java.time.LocalDateTime typealias ArticleId = Long data class Article( val id: ArticleId?, var title: String, var headline: String, var content: String, val addedAt: LocalDateTime? )
其他包括:
-
ArticleRepository接口,它允许业务核心与外部服务进行通信。
-
ArticleService接口,它允许外部应用程序与业务核心进行通信。在usecase包中,ArticleServiceImpl 类 扩展了ArticleService并包含实际的业务逻辑。
数据库适配器的输出端口 ports/output/jpa包包含将数据持久保存到数据库中的组件。 包含:
-
基于core实体的ArticleJpa类。
-
从 Spring JPA 库扩展JpaRepository的ArticleJpaRepository类。
-
ArticleDao类扩展了ArticleRepository,允许业务核心获取和持久化数据。
REST 适配器的输入端口 最后,ports/inputs/rs包包含 Rest Controller,暴露端点以供外部应用程序使用。
为什么架构很重要? 设计软件时存在一组基本要求,称为服务质量要求。这些要求定义了我们在构建高质量软件的过程中必须解决的一些权衡问题,例如可伸缩性、可靠性、可维护性、可测试性和可部署性。 架构很重要,因为如果我们在选择时足够明智,那么适合我们项目的架构模式将帮助我们的软件达到预期的质量,并且也许可以让我们免去一些麻烦。 示例代码可在GitHub上找到。
微服务浅述---架构演进
微服务浅述---架构演进
- 提到架构演进,我们很容易想到‘单体应用---分布式/SOA---微服务’的演进过程,那么为什么会有这个必然演进?演进的过程中遇到了哪些坑?是怎么解决这些坑的?
- 为什么会有这个必然的架构演进?
- 因为痛点驱动。因为互联网公司很容易突然爆发,今年的数据量可能比去年的数据量翻上N倍。那么刚开始的时候公司用的是单体架构,即一个业务逻辑一撸到底。比如电商公司,从前端商品展示,购物车,下单,订单生成,发货,物流等等这些业务逻辑
全部写在一个工程内,数据放在一个库内,部署在一个服务器上。 - 随着业务的增长,系统的数据量大增,慢慢的单体应用就暴露出很多问题。
- 从开发角度来说,对某个业务逻辑进行修改的时候,痛苦至极,因为有可能只是修改一个参数,就要梳理清楚一大块的业务逻辑,然后要理清楚这些涉及业务逻辑的所有代码,运气不好的,会遇到几千行的一个函数,修改完后,要自测,那就要对整个流程进行自测。如果没改好,上线后就有可能导致主流程瘫痪的事故,痛苦至极。
- 从测试角度来讲,只要某个需求改动,就要对涉及这块业务的所有业务进行测试,因为谁也不能百分百确保,这个需求不影响其他正常流程。
- 从数据库角度来说,数据的增加,库和表都会增大,那总是会到某个阈值后,整个系统的性能都会大大降低。且不可持续,数据还在增加,单库单表的承受能力肯定是有限的。
- 从运维角度来说,服务器的各项指标都高居不下。有的业务模块数据量大,有的小,但是控制手段少,很是担心在某个时间点,服务器和数据库都超过他们的承受能力崩溃掉。
- 这个阶段,一般数据量在百万或者千万出头。用户体验卡顿,线上bug不断。这个阶段单体架构的问题都暴露出来了。
- 从管理角度来说,系统增大,团队也肯定随着增大,那么对于团队的分工和配合就有很多问题。
- 上边这个问题,也许可以通过分库分表,优化代码结构等方式来一定程度上缓解上边问题,但是不能从根本上解决问题。
- 因为痛点驱动。因为互联网公司很容易突然爆发,今年的数据量可能比去年的数据量翻上N倍。那么刚开始的时候公司用的是单体架构,即一个业务逻辑一撸到底。比如电商公司,从前端商品展示,购物车,下单,订单生成,发货,物流等等这些业务逻辑
- 那么如何解决上边单体架构的问题呢?那么就是分布式。
- 如何拆分呢?很容易就想到按照业务逻辑进行垂直拆分,将业务分成各个业务模块,每个业务模块独立出去成为单独的系统。即将ERP系统拆分,拆分出来前端网站,用户系统,订单系统,库存系统等等。每个系统都有自己的服务器、数据库、团队等等。
- 分布式下每个系统还是会随着数据和业务的增长而继续膨胀,那么就要继续拆分,并且每个系统之间会有相同的服务进行抽离,这样就慢慢地演变成面向服务的SOA架构。
- 但是就是SOA架构,它的服务粒度还是很粗。需要对服务进行更深一步的拆分,这就演进到了微服务架构。
- 微服务
- 首先第一个问题就是服务如何拆分?有没有什么理论指导?
- 这就要参考康威定律和领域驱动设计。
- 那么首先要解决的问题是各个系统之间如何通信?
- 常用的方式有rpc,http,mq消息中间件等等
- 系统被拆分成众多服务之后,服务之间会产生各种调用,那么如何管理这些服务? 有的服务要做集群,那么如何做负载均衡?有的服务挂掉了如何处理?等等这些问题。这就是所谓的服务治理。服务治理这个概念并不是解决某一个问题,而是解决一堆问题就是服务治理。
- 首先是第一个问题,服务之间会产生各种调用,那么就要在各个服务之中配置它要调用服务的地址信息,一旦一个服务的地址有改动,就要改所有配置了这个服务信息的其它服务,这显然是不行的,这个时候就需要一个注册中心,来管理所有服务的地址信息,服务生产者可以提供服务后,第一步先来注册中心注册,服务消费者需要什么服务可以来注册中心获取对应服务信息,然后再去请求需要的服务。服务中心主要是对内的。
- 不同的微服务聚合成各种聚合服务之后,需要暴露给客户端去调用,而且要监控各个服务的调用情况,那么这个时候就需要一个网关系统,它的主要功能就是根据客户端的请求url解析后,将其分发到不同的目标服务。就是API网关主要是控制外部对内的访问。
- 一般大公司是不会暴露公司服务内部的真实ip的,那么就要做反向代理,通过反向代理来隐藏公司的真实ip。
- 被拆分的服务肯定被调用的频次是不一样的,有的服务就必须做集群,通过多台服务器内跑相同的某个服务,来提高某个服务吞吐能力,
- 在集群场景下,那么多个服务器之间如何控制? 这就是所谓的负载均衡问题。
- 在集群场景下,有的服务是会产生状态的,比如产生session,那么如何解决集群中的session一致性问题?
- 如果在某种情况下,某个服务的服务器挂掉了,不能提供服务了,那么调用它的那个服务也可能挂掉,这样就会产生服务的雪崩效应。
- 那么如何解决雪崩效应呢?那么就要对各个服务节点做一主一备或者一主多备,万一某个服务的服务器挂掉了,备用服务就应马上接替主服务器的位置,提供服务,同事相应的机制去马上重启主服务器,如果主服务器重启成功,又可以对外提供服务,那么就重新回到主服务器的位置,提供服务,否则通知运维人员去检查问题。这就是所谓的高可用。
- 在双十一等场景下,流量会产生很多倍的暴增,那么一般是不能做到百分百保证自己的系统是可以完全保证所有对外服务都可以正常提供的,那么这个场景下就要做一下取舍,万一出现这种情况,就要对于某些不重要的服务停掉,从而保证业务的主流程不受影响。如果流量下降,就又可以开放那些被停掉的次要服务,重新对外提供服务,这就是所谓的服务降级、限流。
- 系统被拆分成众多服务之后,有些服务之间虽然是不同业务模块的,但它们从业务角度来将是同一个事务,即一个服务成功,那么其他服务也必须有结果,
不能产生一个服务有结果后,其他服务没有执行,那么这就是所谓的分布式事务问题。 - 在某个场景下,可以会发生众多服务同时要消耗一个资源,或者集群环境下,同一个服务的多个进程同事消耗一个资源,无论是多个服务还是集群,他们都分布在不同的服务器内,这就是高并发问题。
- 如何解决上边的高并发问题?单体应用中,解决并发问题是用的锁,那么分布式场景下,就要通过分布式锁来解决上述问题。
- 微服务架构下,服务的粒度都非常小,不可能让一个服务占用一个服务器,这样太浪费,大多数情况下,一个服务器的性能完全可以满足多个服务的运行,那么如何让多个服务在同一个服务器内运行呢? 就是通过容器技术,这就是所谓的容器。
- 假如客户端某次调用后发生问题,需要定位问题,但是一个服务内部可以调用了其它服务,其它服务又调用了其它服务,那么如何监控这些服务呢的调用呢?
这就是服务追踪问题,而解决的技术就是链路监控技术。 - 一般情况下,公司开始想微服务架构改造时,要保证现有系统能正常对外提供服务,考虑到现有团队的技术储备等等,必然会用到不同的语言来进行微服务改造,这就是所谓的异构架构。
- 首先第一个问题就是服务如何拆分?有没有什么理论指导?
以上是关于简短解析浅述SpringBoot六边形架构案例的主要内容,如果未能解决你的问题,请参考以下文章