zoukankan      html  css  js  c++  java
  • 搭建基于springboot轻量级读写分离开发框架

    何为读写分离

    读写分离是指对资源的修改和读取进行分离,能解决很多数据库瓶颈,以及代码混乱难以维护等相关的问题,使系统有更好的扩展性,维护性和可用性。

    一般会分三个步骤来实现:
    一. 主从数据库搭建
    信息管理系统的绝大部分瓶颈在数据库,通过搭建主从数据库,写到主数据库,读取从数据库,提高数据库的吞吐量,根据业务需求可以搭建一主一从、一主多从的数据库同步架构。如果报表多的系统,可以搭个一主多从架构,一个从数据库供普通查询,另一个从数据库供报表查询,这样能够避免报表的复杂查询影响客户正常操作。

    二. 读写代码分离
    代码上对读写进行分离。读的逻辑相对简单,几乎不需要做过多的分层封装。大部分业务逻辑在写操作,所以我们需要专注于对写代码的分层、抽象封装。注意: 在写模块涉及到业务数据读取,几乎要实时的,而且基于高内聚的原则,应该封装进写代码类中,读取主数据库。

    三. 进程分离
    将读和写的代码封装到不同的进程,从进程级别避免相互影响,其实就是分布式。实现从进程上解耦,程序运行期间的性能、异常错误不会相互影响,所以系统有相对高的可用性。

    这里多说一句, 如果对写业务按领域拆分到不同的进程,会涉及到分布式事务,在未涉及到高并发、大数据的系统,其实没必要从进程上拆分,分布式对事务不友好,为了处理分布式事务,你需要付出更多的时间和金钱成本。考虑进程拆分,一定要基于实际业务需求再三权衡利弊。很多时候,也许你只需要多一个从数据库、一个缓存、多一台服务器、多几G内存、多几核cpu、优化一下sql 即可解决很多性能上的问题。

    如何搭建

    现在我们搭建一主一从数据库架构, 并且实现从代码上进行读写分离的开发框架,但不涉及进程分离。

    1. 搭建主从数据库

    mariadb 可参考搭建 mariadb 数据库主从同步 或者 https://mariadb.com/kb/en/setting-up-replication/

    2. 基于springboot 搭建开发框架

    2.1 项目结构

    画一下框架的模块结构

    1. api 模块相当于 gateway, 接收和响应请求,还包括鉴权, 参数的校验和组装,调用 command, query 的接口。
    2. common 模块封装一些和业务无关的通用功能类。
    3. query 是读模块,封装非实时的查询接口,查询"从数据库"。
    4. command 是写模块,封装领域的业务逻辑,操作"主数据库"。

    按照上图,用 idea 创建项目结构如下

    对 command 和 query 模块再进行细化

    因为 command 模块我们使用领域驱动开发,所以拆分成服务(Service), 仓储(Repository), ORM, 聚合根(Aggregate)。

    Query 只是简单的查询,我们直接用 Dao 访问数据库,然后把数据转成 DTO 返回。

    根据上图,再细化项目的文档结构

    2.2 配置文件

    假设我们有三个环境, 分别是开发(dev), 测试(uat), 生产(prod)。每个模块都有单独的配置文件。
    api:
    application-api-dev.yml
    application-api-uat.yml
    application-api-prod.yml

    command:
    application-command-dev.yml
    application-command-uat.yml
    application-command-prod.yml

    query:
    application-query-dev.yml
    application-query-uat.yml
    application-query-prod.yml

    在系统启动时,指定使用的环境, api 作为启动项目,添加 bootstrap.yml, 因为 bootstrap.yml 优先于 application.yml 生效,所以可以在 bootstrap.yml 配置启动环境。
    我们启用 dev 环境, bootstrap.yml 内容如下:

    spring:
      profiles:
        active: common-dev,command-dev,query-dev,api-dev
    

    那么,对应的 application-common-dev.yml, application-command-dev.yml, application-query-dev.yml, application-api-dev.yml 配置文件将起效。

    2.3 运行

    在 query 项目添加一个接口

    public interface UserQueryService {
        String getName(Long id);
    }
    

    并实现它

    @Service
    public class UserQueryServiceImpl implements UserQueryService {
        @Override
        public String getName(Long id) {
            return "my name is grissom" + id;
        }
    }
    
    

    在 api 中调用该接口

    
    @RestController
    @RequestMapping("user")
    public class UserController {
        private final UserQueryService userQueryService;
    
        public UserController(UserQueryService userQueryService) {
            this.userQueryService = userQueryService;
        }
    
        @GetMapping("/name/{id}")
        public String name(@PathVariable("id") Long id) {
            return this.userQueryService.getName(id);
        }
    }
    
    

    将 api 作为启动项,配置 application-api-dev.yml, 开放 8003 端口

    server:
      port: 8003
    

    用 postman 请求

    至此,咱们的项目结构已经搭建好。
    下一篇再写如何访问数据库。

    源码

    https://github.com/grissomlau/cqrs-springboot

  • 相关阅读:
    iOS开发UI篇—使用UItableview完成一个简单的QQ好友列表(一)
    iOS开发UI篇—简单介绍静态单元格的使用
    jade反编译
    jade复用
    sublime修改TAB缩进
    jade模板引擎的基本使用
    MongoDB直接执行js脚本
    初识MongoDB
    php练习:每5个商品一排
    MongoDB聚合查询
  • 原文地址:https://www.cnblogs.com/grissom007/p/14389311.html
Copyright © 2011-2022 走看看