当前位置: 首页 > news >正文

海门建网站公司小程序开发公司哪家正规

海门建网站公司,小程序开发公司哪家正规,网站表格怎么做,推广网络平台一、什么是 MySQL 的主从复制 MySQL 的主从复制#xff08;Master-Slave Replication#xff09;是一种将数据从一个主数据库服务器#xff08;主库#xff09;复制到一个或多个从数据库服务器#xff08;从库#xff09;的技术。主库负责所有的数据写操作#xff0c;从…一、什么是 MySQL 的主从复制 MySQL 的主从复制Master-Slave Replication是一种将数据从一个主数据库服务器主库复制到一个或多个从数据库服务器从库的技术。主库负责所有的数据写操作从库则通过读取主库的二进制日志来同步主库的数据变化。主从复制主要用于实现数据的备份、负载分担和高可用性。 二、具体流程 1. 主库记录写操作 当主库执行写操作如 INSERT、UPDATE 或 DELETE时这些操作会被记录到二进制日志binlog中。二进制日志保存了所有数据更改的历史记录这些记录将成为从库同步数据的来源。 步骤主库将所有写操作数据变更记录到二进制日志中。 2. 从库连接主库并读取二进制日志 从库通过一个称为IO 线程的进程与主库建立连接开始读取主库的二进制日志。主库会将日志内容发送给从库的 IO 线程。 步骤从库的 IO 线程连接主库持续接收主库二进制日志的最新内容。 3. 从库将二进制日志写入中继日志 从库的 IO 线程将接收到的主库二进制日志复制到从库的**中继日志relay log**中。中继日志在从库本地保存了一份主库数据变更的副本供从库执行使用。 步骤从库的 IO 线程将接收的日志写入中继日志为数据变更做好准备。 4. 从库应用中继日志执行数据同步 从库的另一个线程称为SQL 线程负责读取中继日志中的内容并逐条在从库上执行以实现数据的同步。每当主库有新的数据变更从库都会从中继日志中获取并执行这些变更从而保持与主库的数据一致。 步骤从库的 SQL 线程从中继日志中读取并执行记录的操作逐步更新从库数据。 5. 持续复制和同步 整个主从复制过程是一个持续的流程只要主库有新的数据变更从库就会自动获取并执行对应的更改从而保持与主库数据的一致性。主从复制会持续保持同步以确保从库能够实时或接近实时地反映主库的最新数据。 步骤主库的所有写操作都会记录到日志中实时同步到从库从库持续读取并执行日志内容更新自身数据。 三、作用和好处 读写分离提高性能 减轻主库压力将大量的读操作分散到从库主库主要负责写操作大大降低了主库的负载压力。提升并发处理能力增加从库的数量可以提升系统的读并发能力处理更多用户的并发请求提升系统整体性能。 高可用性和容错性 数据冗余与容灾主从复制提供了数据的实时备份从库可以在主库发生故障时快速接管服务提高系统的可用性。故障切换当主库出现故障时可以临时将从库升级为主库保障服务持续运行。 负载均衡 分担查询压力多个从库可以共同承担读取请求通过负载均衡算法如轮询、随机等分配请求提升系统的稳定性。避免单点瓶颈读操作分散到不同的从库上执行避免了单一数据库因访问量过大而成为系统瓶颈。 扩展性 水平扩展根据业务增长灵活增加从库数量满足性能需求而无需对主库进行大幅度改造。弹性扩展可以根据实际流量增加或减少从库做到灵活应对负载变化。 数据备份和安全性 数据保护从库可以用于数据备份和容灾防止主库故障导致的数据丢失。快速恢复在数据意外丢失或损坏时可以通过从库恢复主库的数据。 四、在实际应用中的场景与示例 1. 电商平台 在电商平台中用户的浏览和查询操作会产生大量的读请求而订单创建、支付等操作会产生写请求。通过主从复制的读写分离 查询库存、商品详情等高频率的读操作可以由从库承担减轻主库压力。用户下单、支付等写操作由主库负责确保数据的完整性和一致性。 2. 社交媒体或内容网站 在社交媒体应用中大量的内容浏览和搜索会产生大量的读操作而发布、点赞等则是写操作。通过主从复制平台可以 使用从库来承担浏览、查询等操作确保高并发下的快速响应。将写操作指向主库确保用户发布或点赞的实时更新。 五、在 Spring Boot 项目中集成 MySQL 主从复制 在 Spring Boot 项目中集成 MySQL 的主从复制数据同步指的是将 Spring Boot 应用程序连接到配置有主从复制的 MySQL 数据库系统上完成主从数据库的配置管理实现自动的读写分离。具体来说就是通过多数据源配置让 Spring Boot 自动识别是写请求还是读请求并将写请求发送到主库读请求发送到从库。 集成的关键要素 多数据源配置在 Spring Boot 中配置主数据库和从数据库的连接。动态数据源路由在应用层面实现数据源的动态选择读操作使用从库写操作使用主库。读写分离注解或切面利用自定义注解或 AOP 切面控制数据源的切换。 1.配置 MySQL 的主从复制环境 配置 MySQL 的主从复制环境是实现 MySQL 主从复制数据同步的第一步。主要步骤包括设置主库Master和从库Slave并验证主从复制的成功。 1.1 设置主库Master 配置主库是主从复制的第一步。主库负责记录数据变更并将其传递给从库。 1.1.1 修改主库的配置文件 在主库的 MySQL 配置文件中通常位于 /etc/my.cnf 或 /etc/mysql/my.cnf需要启用二进制日志并为主库设置一个唯一的 server-id。在 [mysqld] 部分添加如下配置 [mysqld] server-id1 # 主库的唯一 ID log-binmysql-bin # 启用二进制日志主从复制依赖于此 binlog-do-dbyour_database # 需要同步的数据库名称多个数据库可添加多行server-id用于标识每个 MySQL 实例的唯一标识符主库的 server-id 一般设置为 1。log-bin启用二进制日志这是主从复制的基础。binlog-do-db指定需要同步的数据库多个数据库可以多行设置。 注意如果需要同步多个数据库可以多次添加 binlog-do-db 行例如 binlog-do-dbdatabase1 binlog-do-dbdatabase21.1.2 重启 MySQL 服务 修改配置文件后需要重启 MySQL 以使配置生效 # Linux 系统 sudo systemctl restart mysqld# Windows 系统 net stop mysql net start mysql1.1.3 创建用于复制的用户 在主库中创建一个用于复制的用户并授予 REPLICATION SLAVE 权限。这个用户用于从库连接主库并进行数据同步。 在主库的 MySQL 命令行中执行以下命令 CREATE USER replica_user% IDENTIFIED BY password; GRANT REPLICATION SLAVE ON *.* TO replica_user%; FLUSH PRIVILEGES;replica_user用于复制的用户名可以自定义。password复制用户的密码注意使用强密码。%允许所有远程 IP 访问。如果只允许特定从库连接可以用从库的 IP 地址代替 %。 1.1.4 获取主库的二进制日志信息 为了让从库知道从何处开始复制数据主库需要提供当前的二进制日志位置。可以通过以下命令查看 SHOW MASTER STATUS;命令执行后会输出如下内容 ------------------------------------------------------------ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | ------------------------------------------------------------ | mysql-bin.000001 | 154 | your_database| | ------------------------------------------------------------File当前的二进制日志文件名。Position二进制日志的偏移量从该位置开始读取数据。 建议在生产环境中执行 SHOW MASTER STATUS; 之前可以先执行 FLUSH TABLES WITH READ LOCK; 来锁定表防止数据写入导致的数据不一致。获取信息后再执行 UNLOCK TABLES; 解锁。 1.2 设置从库Slave 配置从库是主从复制的第二步。配置从库连接到主库并开始同步数据。 1.2.1 修改从库的配置文件 在从库的 MySQL 配置文件中通常是 /etc/my.cnf 或 /etc/mysql/my.cnf设置一个唯一的 server-id 并配置中继日志和只读模式。 在 [mysqld] 部分添加以下配置 [mysqld] server-id2 # 从库的唯一 ID不能与主库或其他从库相同 relay-logrelay-log # 设置中继日志文件名前缀 read-only1 # 设置只读模式防止误操作server-id从库的唯一标识符每个从库的 server-id 也需要是唯一的通常从 2 开始。relay-log指定中继日志的前缀用于存储从主库同步的数据。read-only开启只读模式防止意外写入。此模式下拥有 SUPER 权限的用户仍可以写入数据。 1.2.2 重启 MySQL 服务 修改配置文件后重启从库的 MySQL 服务以应用配置 # Linux 系统 sudo systemctl restart mysqld# Windows 系统 net stop mysql net start mysql1.2.3 配置从库连接到主库 在从库的 MySQL 中配置主库信息以便开始复制。需要用到在主库上记录的 File 和 Position 值。 CHANGE MASTER TOMASTER_HOST主库的 IP 地址,MASTER_USERreplica_user,MASTER_PASSWORDpassword,MASTER_LOG_FILEmysql-bin.000001, -- 主库的 File 值MASTER_LOG_POS154; -- 主库的 Position 值MASTER_HOST主库的 IP 地址。MASTER_USER在主库上创建的用于复制的用户如 replica_user。MASTER_PASSWORD复制用户的密码。MASTER_LOG_FILE主库的二进制日志文件名。MASTER_LOG_POS二进制日志的位置偏移量。 1.2.4 启动复制进程 配置完成后启动从库的复制进程以开始从主库复制数据 START SLAVE;1.2.5 查看从库的复制状态 运行以下命令检查从库的状态确认从库已成功连接到主库并开始复制数据 SHOW SLAVE STATUS\GSlave_IO_Running应为 Yes表示从库的 IO 线程正在读取主库的日志。Slave_SQL_Running应为 Yes表示从库的 SQL 线程正在执行主库传递的日志。Last_IO_Error 和 Last_SQL_Error如果存在错误信息会在此处显示。 如果 Slave_IO_Running 或 Slave_SQL_Running 为 No请查看 Last_IO_Error 或 Last_SQL_Error 中的错误消息并根据错误提示排查问题。 1.3 验证主从复制是否成功 在配置完成后验证主从复制的成功性。确保主库的写操作能够被从库正确同步。 1.3.1 在主库上创建测试数据 在主库上选择用于复制的数据库并创建一个测试表插入数据 USE your_database; CREATE TABLE test_table (id INT PRIMARY KEY,name VARCHAR(50) );INSERT INTO test_table (id, name) VALUES (1, Test Data);1.3.2 在从库上检查数据同步情况 在从库上选择相同的数据库查询 test_table 表确认是否同步了主库的数据 USE your_database; SELECT * FROM test_table;如果可以看到 Test Data则表示主从复制配置成功并且工作正常。 1.3.3 验证实时同步效果 在主库上继续插入或更新数据再次在从库上查询验证数据是否能够及时同步。主从复制一般情况下会立即同步延迟较小。 1.4 故障排查 在配置主从复制的过程中可能会遇到以下常见问题 1 从库无法连接到主库 检查网络连接确保主库的防火墙允许从库的 IP 地址访问 MySQL 的 3306 端口。 2 权限问题 用户权限确保在主库上创建的用户拥有 REPLICATION SLAVE 权限。 3 主从版本兼容性问题 版本兼容性确保主库和从库的 MySQL 版本相互兼容推荐使用相同的版本。 4 日志位置不正确 文件和位置错误如果配置的 File 和 Position 不正确可以重新设置主从复制位置。 2.在 Spring Boot 项目中配置多数据源 配置多数据源是实现主从复制的重要步骤。通过多数据源配置Spring Boot 应用可以自动区分并选择主库或从库从而实现读写分离。这一步的具体操作包括添加依赖、配置数据源信息以及配置数据源路由以实现自动选择主库或从库。以下是详细的分步讲解。 2.1 添加必要的依赖 在使用 Spring Data JPA 和 MySQL 多数据源时需要添加以下依赖项 MySQL 驱动支持连接 MySQL 数据库。Spring Data JPA提供 JPA 支持简化数据库操作。HikariCP 连接池Spring Boot 默认的连接池适合高并发环境且支持多数据源配置。 在项目的 pom.xml 中添加以下依赖 dependencies!-- MySQL 驱动 --dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactId/dependency!-- Spring Data JPA --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependency!-- HikariCP 连接池Spring Boot 默认连接池 --dependencygroupIdcom.zaxxer/groupIdartifactIdHikariCP/artifactId/dependency /dependencies2.2 在配置文件中定义主库和从库的数据源信息 接下来需要在 application.properties 中定义主库和从库的连接信息。主库通常用于写操作从库用于读操作。 application.properties 文件内容 # 主库配置 spring.datasource.master.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.master.urljdbc:mysql://主库IP地址:3306/your_database?useSSLfalsecharacterEncodingutf8 spring.datasource.master.username主库用户名 spring.datasource.master.password主库密码# 从库配置 spring.datasource.slave.driver-class-namecom.mysql.cj.jdbc.Driver spring.datasource.slave.urljdbc:mysql://从库IP地址:3306/your_database?useSSLfalsecharacterEncodingutf8 spring.datasource.slave.username从库用户名 spring.datasource.slave.password从库密码说明 spring.datasource.master主库连接信息用于写操作。spring.datasource.slave从库连接信息用于读操作。driver-class-nameMySQL 驱动类名。url数据库连接 URL其中包含数据库的 IP 地址和数据库名称。username 和 password数据库的用户名和密码。 2.3 创建数据源配置类配置主从数据源 在项目中添加一个配置类用于定义主库和从库数据源并通过一个动态数据源实现自动选择主库或从库。 2.3.1 配置主库和从库的数据源 首先我们需要在配置类中定义两个数据源即主库和从库。主库主要用于写操作从库用于读操作。 package com.example.config;import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import org.springframework.boot.jdbc.DataSourceBuilder;Configuration public class DataSourceConfig {// 定义主库数据源Bean(name masterDataSource)ConfigurationProperties(prefix spring.datasource.master)public DataSource masterDataSource() {return DataSourceBuilder.create().build();}// 定义从库数据源Bean(name slaveDataSource)ConfigurationProperties(prefix spring.datasource.slave)public DataSource slaveDataSource() {return DataSourceBuilder.create().build();} }说明 ConfigurationProperties这个注解将 application.properties 中 spring.datasource.master 和 spring.datasource.slave 配置的信息绑定到 masterDataSource 和 slaveDataSource 上。这样Spring Boot 会自动读取配置文件中的主从库信息并将它们分别注入到两个数据源对象中。 DataSourceBuilder这是 Spring 提供的一个工具类通过它可以根据配置文件构建 DataSource 对象。DataSource 是与数据库连接的核心组件主要用于管理数据库连接、连接池等信息。 2.3.2 动态数据源路由 为了实现主从分离我们需要根据请求自动选择主库或从库的数据源。AbstractRoutingDataSource 是 Spring 提供的一个抽象类可以根据用户定义的路由规则动态选择数据源。 创建 DynamicDataSource 类该类继承自 AbstractRoutingDataSource通过设置键值映射来实现数据源选择。 package com.example.config;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {private static final ThreadLocalString contextHolder new ThreadLocal();// 设置当前线程的数据源主库或从库public static void setDataSource(String dataSourceKey) {contextHolder.set(dataSourceKey);}// 清除当前线程的数据源public static void clearDataSource() {contextHolder.remove();}// 确定当前数据源由 AbstractRoutingDataSource 调用Overrideprotected Object determineCurrentLookupKey() {return contextHolder.get();} }代码详解 contextHolder使用 ThreadLocal 存储当前线程的数据源标识master 或 slave。ThreadLocal 确保每个线程拥有独立的变量副本不会干扰其他线程。 setDataSource用于设置当前线程的数据源通过传入 master 或 slave 来指定主库或从库。 clearDataSource用于清除当前线程的数据源避免数据源信息在线程之间混淆。 determineCurrentLookupKey这是 AbstractRoutingDataSource 提供的方法它会在每次数据库操作时调用。根据 contextHolder 中的数据源标识选择主库或从库。 2.3.3 将主从数据源注入到动态数据源 我们需要将主库和从库的数据源注入到动态数据源中并根据不同的业务需求自动选择。 Bean(name dynamicDataSource) public DataSource dynamicDataSource(Qualifier(masterDataSource) DataSource masterDataSource,Qualifier(slaveDataSource) DataSource slaveDataSource) {MapObject, Object targetDataSources new HashMap();targetDataSources.put(master, masterDataSource);targetDataSources.put(slave, slaveDataSource);DynamicDataSource dynamicDataSource new DynamicDataSource();dynamicDataSource.setDefaultTargetDataSource(masterDataSource); // 设置默认的数据源dynamicDataSource.setTargetDataSources(targetDataSources); // 将主库和从库的数据源加入路由return dynamicDataSource; }代码详解 Qualifier指定 masterDataSource 和 slaveDataSource通过依赖注入的方式将主库和从库的数据源传入 dynamicDataSource。 targetDataSources将 master 和 slave 作为键分别映射到 masterDataSource 和 slaveDataSource。DynamicDataSource 会通过 determineCurrentLookupKey 方法自动选择对应的数据源。 setDefaultTargetDataSource设置默认的数据源。在没有指定数据源的情况下系统会使用默认数据源一般为主库。 2.3.4 配置 EntityManagerFactory 使用动态数据源 对于使用 JPA 的项目EntityManagerFactory 是 JPA 的核心组件之一。它负责管理实体管理器处理 JPA 的持久化操作。这里需要将 EntityManagerFactory 配置为使用动态数据源以实现主从分离。 Bean(name entityManagerFactory) public LocalContainerEntityManagerFactoryBean entityManagerFactory(Qualifier(dynamicDataSource) DataSource dynamicDataSource) {LocalContainerEntityManagerFactoryBean em new LocalContainerEntityManagerFactoryBean();em.setDataSource(dynamicDataSource); // 使用动态数据源em.setPackagesToScan(com.example.entity); // 实体类包名em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); // 设置 JPA 供应商为 Hibernatereturn em; }代码详解 setDataSource设置 JPA 的数据源为 dynamicDataSource这样 JPA 会根据动态数据源的路由选择合适的数据源。 setPackagesToScan指定 JPA 实体类所在的包路径JPA 会扫描该包中的实体类进行数据库操作的映射。 HibernateJpaVendorAdapter设置 JPA 的供应商适配器。这里我们使用 Hibernate 作为 JPA 的实现它提供了 Hibernate 特有的优化和配置支持。 通过配置 EntityManagerFactory 使用 dynamicDataSource我们可以让 JPA 在操作数据库时自动根据业务需要切换到主库或从库从而实现主从分离和读写分离。 2.3.5 配置事务管理器 Spring Data JPA 默认需要一个事务管理器来管理事务。我们需要为动态数据源配置一个 JpaTransactionManager以确保事务操作可以正确地应用于当前选择的数据源主库或从库。 Bean(name transactionManager) public JpaTransactionManager transactionManager(Qualifier(entityManagerFactory) LocalContainerEntityManagerFactoryBean entityManagerFactory) {return new JpaTransactionManager(entityManagerFactory.getObject()); }代码详解 JpaTransactionManagerSpring 提供的 JPA 事务管理器它会自动处理 EntityManager 的创建和关闭并确保在事务中对数据库操作的 ACID 特性原子性、一致性、隔离性、持久性。 entityManagerFactory.getObject()将 entityManagerFactory配置了动态数据源的实体管理器工厂传递给 JpaTransactionManager。这样事务管理器会根据动态数据源路由来管理事务确保事务一致性。 3.实现数据源的动态切换 为了实现数据库的主从切换使得 Spring Boot 项目可以根据操作类型自动选择主库或从库我们需要实现数据源的动态切换。实现动态切换的关键步骤包括定义自定义注解、创建 AOP 切面在方法执行时动态地决定使用哪个数据源。 3.1 创建 DataSource 注解用于标识使用哪个数据源 首先我们创建一个自定义注解 DataSource用于标识在特定方法或类上指定的数据源类型如主库 master 或从库 slave。有了这个注解之后我们可以在代码中灵活地指定哪些操作使用主库哪些操作使用从库。 package com.example.annotation;import java.lang.annotation.*;Target({ElementType.METHOD, ElementType.TYPE}) // 可以用在方法或类上 Retention(RetentionPolicy.RUNTIME) // 在运行时保留便于通过反射获取 Documented public interface DataSource {String value() default master; // 默认使用主库 }注解参数说明 Target定义注解的使用位置ElementType.METHOD 表示可以作用于方法ElementType.TYPE 表示可以作用于类。 Retention指定注解的保留策略为 RUNTIME即该注解会保留到运行时并且可以通过反射获取这样切面类可以在运行时识别注解。 value注解的属性用来指定数据源类型默认为 master表示主库。我们可以在使用注解时通过设置 DataSource(slave) 来指定从库。 3.2 创建 DataSourceAspect 切面类根据注解动态切换数据源 AOP面向切面编程可以在方法调用前后动态地切入代码逻辑。在这里我们编写一个 AOP 切面用于在方法调用之前根据 DataSource 注解的值设置数据源。在方法调用之后清除数据源的标识以确保不会影响后续操作。 package com.example.aspect;import com.example.annotation.DataSource; import com.example.config.DynamicDataSource; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component;Aspect Component public class DataSourceAspect {// 定义切点匹配带有 DataSource 注解的方法或类Pointcut(annotation(com.example.annotation.DataSource) || within(com.example.annotation.DataSource))public void dataSourcePointCut() {}// 在方法执行前根据注解的值切换数据源Before(dataSourcePointCut())public void before(JoinPoint point) {String dataSource master; // 默认使用主库Class? targetClass point.getTarget().getClass();MethodSignature signature (MethodSignature) point.getSignature();// 获取方法上的 DataSource 注解DataSource ds signature.getMethod().getAnnotation(DataSource.class);if (ds ! null) {dataSource ds.value();} else if (targetClass.isAnnotationPresent(DataSource.class)) {// 如果方法上没有注解则读取类上的 DataSource 注解ds targetClass.getAnnotation(DataSource.class);if (ds ! null) {dataSource ds.value();}}// 设置当前线程的数据源标识DynamicDataSource.setDataSource(dataSource);}// 在方法执行后清除数据源标识After(dataSourcePointCut())public void after(JoinPoint point) {DynamicDataSource.clearDataSource();} }切面类代码详解 Pointcut定义切点 dataSourcePointCut用于匹配所有带有 DataSource 注解的方法或类。这意味着我们可以在方法上、类上使用 DataSource 来控制数据源选择。 Before在目标方法执行之前触发 before 方法。 MethodSignature通过 MethodSignature 可以获取方法的注解。 dataSource默认值为 master主库。首先检查方法上的 DataSource 注解如果没有找到再检查类上的 DataSource 注解。 DynamicDataSource.setDataSource(dataSource)根据注解值设置当前线程使用的数据源主库或从库。这使得后续的数据库操作将根据注解指定的数据源执行。 After在目标方法执行后触发 after 方法用于清除当前线程的数据源标识以避免线程复用时对其他请求产生干扰。DynamicDataSource.clearDataSource() 方法会移除当前线程的数据源标识。 4.在业务代码中使用 4.1 使用 DataSource 注解 在业务代码中可以在需要使用主库或从库的业务方法上添加 DataSource 注解。默认情况下DataSource 注解的 value 属性是 master表示主库。我们可以在查询类方法上标记 DataSource(slave) 以使用从库从而实现读写分离。 4.1.1.在服务层使用 DataSource 注解 假设我们有一个 UserService 服务类该类提供了查询用户列表和保存用户的功能。我们可以通过 DataSource 注解指定使用的数据库。 import com.example.annotation.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List;Service public class UserService {Autowiredprivate UserRepository userRepository;// 使用从库slave进行读取操作DataSource(slave)public ListUser getUsers() {// 数据库查询操作这里会通过切面选择从库return userRepository.findAll();}// 使用主库master进行写入操作DataSource(master)public void saveUser(User user) {// 数据库写入操作这里会通过切面选择主库userRepository.save(user);} }示例说明 getUsers 方法由于标注了 DataSource(slave) 注解因此在执行 getUsers 方法时会选择从库作为当前数据源从而使查询操作通过从库完成减轻主库压力。 saveUser 方法标注了 DataSource(master) 注解因此在执行 saveUser 方法时会选择主库作为当前数据源从而保证数据写入操作在主库上进行确保数据的一致性。 4.1.2.在 DAO 层数据持久层使用 DataSource 注解 假设我们将数据源控制进一步细化到 DAO 层。例如在 UserRepository 中的查询和保存方法上分别指定数据源。 import com.example.annotation.DataSource; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List;Repository public interface UserRepository extends JpaRepositoryUser, Long {// 使用从库slave进行读取操作DataSource(slave)ListUser findByName(String name);// 使用主库master进行写入操作DataSource(master)User save(User user); }示例说明 findByName 方法该方法标注了 DataSource(slave)因此在调用 findByName 时数据查询操作将通过从库完成。 save 方法该方法标注了 DataSource(master)确保数据写入操作始终通过主库进行保证了数据的完整性。 注意将 DataSource 注解放在服务层和 DAO 层都会生效。实际应用中可以根据业务逻辑的复杂程度来决定在哪一层实现数据源的切换。 4.2 确保读操作走从库写操作走主库 通过在业务方法中使用 DataSource 注解可以实现以下的逻辑 1.读操作走从库在查询数据的方法上添加 DataSource(slave)使这些方法通过从库执行。 从库通常用于处理读操作。这样可以分担主库的负载提升系统的读取性能。因为从库的数据来自主库的复制存在一定延迟所以一般不用于强一致性要求的场景而适合对实时性要求较低的查询场景。 2.写操作走主库在插入、更新、删除数据的方法上添加 DataSource(master)确保这些操作通过主库执行。 主库是数据的源头负责处理写入、更新等操作以确保数据的准确性和一致性。这样可以避免因为复制延迟导致的数据不一致问题。 示例在 ProductService 中实现读写分离 import com.example.annotation.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;Service public class ProductService {Autowiredprivate ProductRepository productRepository;// 使用从库读取产品列表DataSource(slave)public ListProduct getAllProducts() {// 从库执行查询return productRepository.findAll();}// 使用主库保存产品信息DataSource(master)public void addProduct(Product product) {// 主库执行插入操作productRepository.save(product);}// 更新产品信息使用主库DataSource(master)public void updateProduct(Product product) {// 主库执行更新操作productRepository.save(product);}// 删除产品信息使用主库DataSource(master)public void deleteProductById(Long productId) {// 主库执行删除操作productRepository.deleteById(productId);} }代码解释 getAllProducts() 方法 使用 DataSource(slave) 注解从库将执行该方法中的查询操作。适用于读取类操作减轻主库压力。 addProduct()、updateProduct() 和 deleteProductById() 方法 这些方法使用 DataSource(master) 注解因此会走主库。适用于写操作新增、修改、删除确保数据的强一致性和实时性。 4.3 注意事项 在实现读写分离时以下几点需要注意 主从数据一致性从库的数据源于主库的复制所以存在一定的延迟。对于不允许数据延迟的操作建议强制使用主库。比如订单支付或库存更新等操作通常对实时性要求较高应直接走主库。 事务管理在事务中进行读操作可能会导致数据源切换失效因为在事务中默认会使用主库。这种情况下可以使用 Transactional(readOnly true) 标记方法为只读事务让 Spring 在事务中仍使用从库。 线程安全因为数据源切换是基于 ThreadLocal 实现的所以多线程环境下可以安全地设置和切换数据源标识。然而如果有异步操作可能会导致数据源信息传递失效需要特别注意。 5.测试和验证 完成 Spring Boot 项目中多数据源的配置之后需要测试项目是否能够正确地实现读写分离。主要步骤包括检查 MySQL 主库和从库的服务状态、启动项目、编写并运行测试类以及验证主从数据库的数据同步情况。 5.1 检查 MySQL 主库和从库的服务状态 要确保 Spring Boot 项目能够连接到主从数据库首先需要确认 MySQL 主库和从库的服务状态。如果主库和从库未启动Spring Boot 应用将无法连接数据库。 5.1.1 使用命令行检查 MySQL 服务状态 在主库和从库的服务器上可以使用以下命令检查 MySQL 服务状态 # 检查 MySQL 服务是否正在运行 sudo systemctl status mysql如果显示 active (running)则表示 MySQL 服务正在运行。 5.1.2 使用命令行启动 MySQL 服务 如果 MySQL 服务未运行可以使用以下命令启动 # 启动 MySQL 服务 sudo systemctl start mysql启动服务后可以再次使用 status 命令检查服务状态确保 MySQL 服务已启动。 注意如果主库和从库在不同的服务器上您需要分别在主库服务器和从库服务器上执行上述命令。 5.2 使用 IntelliJ IDEA 启动 Spring Boot 项目 在确认 MySQL 主库和从库均已启动后可以启动 Spring Boot 项目。 5.2.1 在 IntelliJ IDEA 中启动 Spring Boot 项目 打开项目在 IntelliJ IDEA 中打开您的 Spring Boot 项目。定位主类在项目的 src/main/java 目录中找到主类通常是带有 SpringBootApplication 注解的类比如 YourApplication 类。运行项目右键点击主类文件选择“Run ‘YourApplication’”运行 YourApplication选项。IDEA 将会在控制台显示启动日志。 5.2.2 检查控制台输出 项目启动后检查 IDEA 控制台的日志输出确保没有报错信息。如果看到类似以下内容则说明项目启动成功 INFO 12345 --- [main] com.example.YourApplication : Started YourApplication in 3.456 seconds (JVM running for 4.123)5.3 编写测试类测试读写操作是否按照预期走对应的数据源 在项目启动后我们可以编写测试类通过测试 Spring Boot 项目中是否实现了主从分离读操作走从库、写操作走主库。 5.3.1 创建测试类 在项目的 src/test/java 目录下创建一个新的测试类例如 UserServiceTest用于测试服务类中的读写方法。以下是测试类的示例代码 import com.example.service.UserService; import com.example.model.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;SpringBootTest public class UserServiceTest {Autowiredprivate UserService userService;// 测试读操作Testpublic void testReadOperation() {// 调用读取用户的方法System.out.println(Executing read operation (should use slave database)...);userService.getUsers();}// 测试写操作Testpublic void testWriteOperation() {// 创建一个新的用户User user new User();user.setName(Test User);user.setEmail(testuserexample.com);// 调用保存用户的方法System.out.println(Executing write operation (should use master database)...);userService.saveUser(user);} }代码说明 SpringBootTest该注解用于在测试类中启动 Spring Boot 上下文。它会自动加载配置文件和应用上下文确保测试类中可以注入依赖。Autowired注入 UserService以便在测试方法中调用 getUsers 和 saveUser 方法。Test每个测试方法都使用 Test 注解表明这是一个测试用例测试框架会自动运行带有 Test 的方法。 测试类的测试方法 testReadOperation测试从库的读取操作。 该方法会调用 userService.getUsers()这应该会使用从库来执行查询操作。我们可以在日志中确认是否成功走到了从库。 testWriteOperation测试主库的写入操作。 该方法会创建一个新用户并调用 userService.saveUser(user)应该会使用主库来执行插入操作。可以在日志中查看是否成功使用主库。 5.3.3 在 IntelliJ IDEA 中运行测试 在 IntelliJ IDEA 中可以通过以下步骤运行测试类 运行单个测试方法在 testReadOperation 或 testWriteOperation 方法上右键点击选择“Run ‘testReadOperation’”或“Run ‘testWriteOperation’”来运行特定测试。运行整个测试类在 UserServiceTest 类名上右键点击选择“Run ‘UserServiceTest’”以运行所有测试方法。 5.3.4 检查测试输出 在控制台中查看输出信息。如果您在 DynamicDataSource 类中添加了日志信息可以看到类似以下的日志 Switching to data source: slave Executing read operation (should use slave database)... Switching to data source: master Executing write operation (should use master database)...读操作日志如果 testReadOperation 的日志显示 Switching to data source: slave说明读操作成功走了从库。写操作日志如果 testWriteOperation 的日志显示 Switching to data source: master说明写操作成功走了主库。 5.4 检查主从数据库的数据同步 在验证读写操作走了正确的数据源后还需要检查主从数据库的数据同步情况以确认主库的数据更改是否成功同步到从库。 5.4.1 执行写入操作检查数据同步 运行写入测试方法通过 testWriteOperation 或直接调用服务中的写入方法向主库插入新数据。 在主库中检查数据连接到主库执行以下查询确认数据是否成功插入 SELECT * FROM your_database.users WHERE name Test User;在从库中检查数据同步稍等片刻后连接到从库执行相同的查询检查数据是否已同步 SELECT * FROM your_database.users WHERE name Test User;如果从库中也能查询到这条记录则表明主库的数据成功同步到了从库。 5.4.2 执行更新操作检查数据同步 运行更新操作在主库中更新记录的某个字段例如通过 userService.updateUser(user) 方法更新 email 字段假设该方法存在或直接在主库执行更新 SQL 语句 UPDATE your_database.users SET email updateduserexample.com WHERE name Test User;在从库中检查数据同步稍等片刻后在从库执行相同的查询确认 email 字段是否已更新为 updateduserexample.com。 5.4.3 执行删除操作检查数据同步 运行删除操作通过 userService.deleteUserById(userId) 方法假设存在或直接在主库执行删除语句 DELETE FROM your_database.users WHERE name Test User;在从库中检查数据同步在从库中执行以下查询确认数据是否已同步删除 SELECT * FROM your_database.users WHERE name Test User;如果查询结果为空则表明删除操作已成功同步到从库。
http://www.hkea.cn/news/14365548/

相关文章:

  • 网站特效360浏览器屏蔽某网站怎么做
  • 企业网站建立流程的第一步是什么官方网站做兼职
  • 西青做网站温州市网站
  • 找产品代理去哪个网站网站每年要交钱吗
  • 苏州做网站建设公司广州骏域网站建设专家 V
  • 专业建站模板商城网站备案需要什么
  • 网站模板展示商城网站建设是 什么软件
  • wordpress汉化器wordpress dx seo
  • 帝国做网站是选择静态还是伪静态网站开发需求规格说明书
  • 代理商门户网站开发设计wordpress主题下载
  • 中国最有名的网站建设公司俄罗斯网站开发
  • 新站网站建设外贸网站搭建服务商
  • 技术教程优化搜索引擎整站wordpress静态博客主题
  • 苏州园科生态建设集团网站全屏产品网站
  • 彩票网站的推荐怎么做mi2设计公司网站
  • 网站搭建是什么专业小程序怎么做出来的
  • wordpress网站在哪里修改密码石家庄建设银行网站
  • 龙溪网站制作网站链接交换
  • 扬中网站建设门户报价深圳餐饮设计公司排名
  • 图片生成链接seo整站优化外包公司
  • 网站排名优化软件企业网站怎样做可以搜索到
  • 南宁企业自助建站系统长沙网站搭建
  • 企业手机网站建设唐山微信小程序开发公司
  • 网站空间域名维护协议金属材料网站建设
  • 做设计的有什么网站wordpress推荐链接
  • 怎么做报名网站画册设计说明
  • 南通手机建站模板ios wordpress fixed
  • 赣州市建设局建管科网站工作作风方面对照检查材料
  • 网站建设有没有资质电商网站开发图书
  • dz门户做视频网站从什么网站找做app的代码