何为读写分离

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

一般会分三个步骤来实现:

一. 主从数据库搭建

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

二. 读写代码分离

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

三. 进程分离

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

这里多说一句, 如果对写业务按领域拆分到不同的进程,会涉及到分布式事务,在未涉及到高并发、大数据的系统,其实没必要从进程上拆分,分布式对事务不友好,为了处理分布式事务,你需要付出更多的时间和金钱成本。考虑进程拆分,一定要基于实际业务需求再三权衡利弊。很多时候,也许你只需要多一个从数据库、一个缓存、多一台服务器、多几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

搭建基于springboot轻量级读写分离开发框架的更多相关文章

  1. 搭建基于MySQL的读写分离工具Amoeba

    搭建基于MySQL的读写分离工具Amoeba: Amoeba工具是实现MySQL数据库读写分离的一个工具,前提是基于MySQL主从复制来实现的: 实验环境(虚拟机): 主机 角色 10.10.10.2 ...

  2. Mycat搭建负载均衡,读写分离的Mysql集群

    Mycat搭建负载均衡,读写分离的Mysql集群 准备环境 1.mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz 2.Mycat-server-1.6.7.4-te ...

  3. 基于SpringBoot前后端分离的点餐系统

    基于SpringBoot前后端分离的点餐系统 开发环境:主要采用Spring boot框架和小程序开发 项目简介:点餐系统,分成卖家端和买家端.买家端使用微信小程序开发,实现扫码点餐.浏览菜单.下单. ...

  4. SpringBoot数据库读写分离之基于Docker构建主从数据库同步实例

    看了好久的SpringBoot结合MyBatista实现读写,但是一直没有勇气实现他,今天终于接触到了读写分离的东西,读写分离就是讲读操作执行在Slave数据库(从数据库),写操作在Master数据库 ...

  5. Mysql8.0主从复制搭建,shardingsphere+springboot+mybatis读写分离

    1.安装mysql8.0 首先需要在192.167.3.171上安装JDK. 下载mysql安装包,https://dev.mysql.com/downloads/,找到以下页面下载. 下载后放到li ...

  6. springboot实现读写分离(基于Mybatis,mysql)

    近日工作任务较轻,有空学习学习技术,遂来研究如果实现读写分离.这里用博客记录下过程,一方面可备日后查看,同时也能分享给大家(网上的资料真的大都是抄来抄去,,还不带格式的,看的真心难受). 完整代码:h ...

  7. SpringBoot Mybatis 读写分离配置(山东数漫江湖)

    为什么需要读写分离 当项目越来越大和并发越来大的情况下,单个数据库服务器的压力肯定也是越来越大,最终演变成数据库成为性能的瓶颈,而且当数据越来越多时,查询也更加耗费时间,当然数据库数据过大时,可以采用 ...

  8. SQL Server、MySQL主从搭建,EF Core读写分离代码实现

    一.SQL Server的主从复制搭建 1.1.SQL Server主从复制结构图 SQL Server的主从通过发布订阅来实现 1.2.基于SQL Server2016实现主从 新建一个主库&quo ...

  9. MySQL集群(三)mysql-proxy搭建负载均衡与读写分离

    前言 前面学习了主从复制和主主复制,接下来给大家分享一下怎么去使用mysql-proxy这个插件去配置MySQL集群中的负载均衡以及读写分离. 注意:这里比较坑的就是mysql-proxy一直没有更新 ...

随机推荐

  1. canvas多重阴影发光效果

    canvas多重阴影发光效果 前言 在一个项目中,客户提了一个发光的效果,效果图如下: 阴影 有的人可能会说,这个用阴影其实就可以实现.但是从图中可以看出,是一个比较强烈的发光效果.实际的应用过程中我 ...

  2. Puzzle (II) UVA - 519

    题目链接: https://vjudge.net/problem/UVA-519 思路: 剪枝+回溯 这个题巧妙的是他按照表格的位置开始搜索,也就是说表格是定的,他不断用已有的图片从(0,0)开始拼到 ...

  3. CSAPP:Lab0 -Docker搭建纯净Linux环境

    1. 安装docker 在mac-os下我们可以利用homebrew很容易的安装docker. brew install docker 当然去官网下载也很容易 Empowering App Devel ...

  4. three.js cannon.js物理引擎之约束

    今天郭先生继续说cannon.js,主演内容就是点对点约束和2D坐标转3D坐标.仍然以一个案例为例,场景由一个地面.若干网格组成的约束体和一些拥有初速度的球体组成,如下图.线案例请点击博客原文. 下面 ...

  5. Array.of使用实例

    Array.of是es6新增的API,其实粗暴点理解,光看of,就可以猜到它是数组的意思,所以猜测可以用来把字符串转换成数组. 像这样的table,有批量删除和单个删除的功能,,但是又不想写两个方法, ...

  6. Docker相关简介以及使用方法

    Docker: 可以把它看作是一个软件,在这个软件当中呢,还可以安装其他的软件,还可以把软件所需要的环境依赖一起添加进来,这样让开发人员的程序在不同的环境当中都可以流转起来,避免了程序出现" ...

  7. 写给 Linux 初学者的一封信

    大家好,我是肖邦. 这篇文章是写给 Linux 初学者的,我会分享一些作为初学者应该知道的一些东西,这些内容都是本人从事 Linux 开发工作多年的心得体会,相信会对初学者有所帮助.如果你是 Linu ...

  8. Java安全之ysoserial-JRMP模块分析(一)

    Java安全之ysoserial-JRMP模块分析(一) 首发安全客:Java安全之ysoserial-JRMP模块分析(一) 0x00 前言 在分析到Weblogic后面的一些绕过方式的时候,分析到 ...

  9. IDEA安装问题解决

    一,安装正确的jdk和idea版本 首先在控制面查看电脑位数,电脑是64位的,安装64位的jdk和idea 二.打开正常的快捷键 有两个启动项,打开对应位数的 三,权限问题 如果弹出不能加载jvm的提 ...

  10. XCTF-phoenix100

    前期工作 查壳无壳,界面是普通的输入flag点击验证 逆向分析 文件结构只有一个MainActively,查看MainActively代码 public class MainActivity exte ...