Spring Boot3 配合ProxySQL实现对 MySQL 主从同步的读写分离和负载平衡 ...

打印 上一主题 下一主题

主题 844|帖子 844|积分 2532

ProxySQL 配合 Spring Boot 使用,重要的目的是在 Spring Boot 应用程序中实现对 MySQL 主从同步的读写分离和负载平衡。如许,你可以使用 ProxySQL 主动将写操作路由到主库,而将读操作路由到从库。
1. 预备工作

确保你的 MySQL 主从同步环境和 ProxySQL 已经乐成配置并正常工作。接下来,我们将举行以下几个步骤:


  • 配置 Spring Boot 毗连 ProxySQL。
  • 配置 数据源 来支持读写分离。
2. 修改 Spring Boot 配置

在 Spring Boot 项目中,配置数据库毗连时,使用 ProxySQL 作为 MySQL 的代理。你需要将 Spring Boot 的 数据源配置 举行一些调整,以支持读写分离。
1.1 配置 application.yml(或 application.properties)

你可以在 application.yml 中配置多个数据源,分别对应主库和从库。ProxySQL 会作为一个代理处理读写分离。
示例:application.yml

  1. spring:
  2.   datasource:
  3.     # 主数据源 (写库)
  4.     primary:
  5.       url: jdbc:mysql://127.0.0.1:6033/mydb
  6.       username: your_user
  7.       password: your_password
  8.       driver-class-name: com.mysql.cj.jdbc.Driver
  9.       hikari:
  10.         maximum-pool-size: 10
  11.         minimum-idle: 5
  12.         pool-name: PrimaryPool
  13.     # 从数据源 (读库)
  14.     secondary:
  15.       url: jdbc:mysql://127.0.0.1:6033/mydb
  16.       username: your_user
  17.       password: your_password
  18.       driver-class-name: com.mysql.cj.jdbc.Driver
  19.       hikari:
  20.         maximum-pool-size: 10
  21.         minimum-idle: 5
  22.         pool-name: SecondaryPool
  23.   # 设置数据源的路由策略
  24.   jpa:
  25.     hibernate:
  26.       ddl-auto: update
  27.     properties:
  28.       hibernate:
  29.         dialect: org.hibernate.dialect.MySQL8Dialect
  30.     show-sql: true
  31.     database-platform: org.hibernate.dialect.MySQL8Dialect
复制代码
在这个配置文件中:


  • 主数据源(primary)用于写入操作,毗连到 ProxySQL 的主库。
  • 从数据源(secondary)用于读取操作,毗连到 ProxySQL 的从库。
ProxySQL 会根据 SQL 语句的范例(SELECT 路由到从库,INSERT/UPDATE 路由到主库)主动分配流量。
1.2 配置 DataSource 路由

Spring Boot 默认只支持单个数据源。如果你需要同时配置多个数据源(主从分离),需要界说一个 数据源路由 类,将哀求的数据库毗连动态路由到主库或从库。
  1. @Configuration
  2. @EnableTransactionManagement
  3. @EnableJpaRepositories(basePackages = "com.example.repository")
  4. public class DataSourceConfig {
  5.     @Primary
  6.     @Bean(name = "primaryDataSource")
  7.     @ConfigurationProperties(prefix = "spring.datasource.primary")
  8.     public DataSource dataSource() {
  9.         return DataSourceBuilder.create().build();
  10.     }
  11.     @Bean(name = "secondaryDataSource")
  12.     @ConfigurationProperties(prefix = "spring.datasource.secondary")
  13.     public DataSource secondaryDataSource() {
  14.         return DataSourceBuilder.create().build();
  15.     }
  16.     // 配置EntityManagerFactory和TransactionManager
  17.     @Bean(name = "entityManagerFactory")
  18.     public LocalContainerEntityManagerFactoryBean entityManagerFactory(
  19.             EntityManagerFactoryBuilder builder,
  20.             @Qualifier("primaryDataSource") DataSource dataSource) {
  21.         return builder
  22.                 .dataSource(dataSource)
  23.                 .packages("com.example.model") // 你的实体类包路径
  24.                 .persistenceUnit("primary")
  25.                 .build();
  26.     }
  27.     @Bean(name = "transactionManager")
  28.     public PlatformTransactionManager transactionManager(
  29.             @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {
  30.         return new JpaTransactionManager(entityManagerFactory);
  31.     }
  32. }
复制代码
在这个配置中,我们界说了两个数据源:primaryDataSource 和 secondaryDataSource,分别毗连到 ProxySQL 的主库和从库。
3. 实现动态数据源路由

为了动态选择使用主库还是从库,你可以使用一个 AbstractRoutingDataSource 来实现动态的数据源路由。
  1. public class DynamicDataSource extends AbstractRoutingDataSource {
  2.     @Override
  3.     protected Object determineCurrentLookupKey() {
  4.         // 判断当前线程中是否有读请求或者写请求,选择数据源
  5.         return DataSourceContextHolder.getDataSourceType();
  6.     }
  7. }
复制代码
然后创建一个 DataSourceContextHolder 用来管理当火线程的数据源范例。
  1. public class DataSourceContextHolder {
  2.     private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
  3.     public static void setDataSourceType(String dataSourceType) {
  4.         contextHolder.set(dataSourceType);
  5.     }
  6.     public static String getDataSourceType() {
  7.         return contextHolder.get();
  8.     }
  9.     public static void clearDataSourceType() {
  10.         contextHolder.remove();
  11.     }
  12. }
复制代码
4. 配置 Service 层的读写分离

接下来,你需要在服务层中手动切换读写操作的数据源。通常,你可以通过注解来区分读操作和写操作。
  1. @Service
  2. public class UserService {
  3.     @Transactional
  4.     public void saveUser(User user) {
  5.         // 使用主库保存数据
  6.         DataSourceContextHolder.setDataSourceType("primary");
  7.         userRepository.save(user);
  8.         DataSourceContextHolder.clearDataSourceType();
  9.     }
  10.     public User getUser(Long id) {
  11.         // 使用从库查询数据
  12.         DataSourceContextHolder.setDataSourceType("secondary");
  13.         User user = userRepository.findById(id).orElse(null);
  14.         DataSourceContextHolder.clearDataSourceType();
  15.         return user;
  16.     }
  17. }
复制代码
在上面的代码中,saveUser 方法会选择主库,而 getUser 方法会选择从库。
5. 配置 Spring AOP 主动切换数据源(可选)

你可以通过 AOP 来简化读写分离的配置,使得你不需要手动设置数据源范例。只需在方法上使用自界说注解(如 @ReadOnly 和 @WriteOnly),主动切换数据源。
自界说注解:

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface ReadOnly {
  4. }
  5. @Target(ElementType.METHOD)
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface WriteOnly {
  8. }
复制代码
创建 AOP 切面:

  1. @Aspect
  2. @Component
  3. public class DataSourceAspect {
  4.     @Before("@annotation(ReadOnly)")
  5.     public void setReadOnlyDataSource() {
  6.         DataSourceContextHolder.setDataSourceType("secondary");
  7.     }
  8.     @Before("@annotation(WriteOnly)")
  9.     public void setWriteOnlyDataSource() {
  10.         DataSourceContextHolder.setDataSourceType("primary");
  11.     }
  12.     @After("@annotation(ReadOnly) || @annotation(WriteOnly)")
  13.     public void clearDataSource() {
  14.         DataSourceContextHolder.clearDataSourceType();
  15.     }
  16. }
复制代码
在这段代码中:


  • 使用 @ReadOnly 注解的方法将会切换到从库。
  • 使用 @WriteOnly 注解的方法将会切换到主库。
6. 总结

通过以上步骤,你可以将 ProxySQL 与 Spring Boot 集成,实现 MySQL 主从同步的读写分离和负载平衡。


  • ProxySQL 作为 MySQL 的代理,负责将读哀求路由到从库,写哀求路由到主库。
  • Spring Boot 通过配置多个数据源和动态路由来实现读写分离。
  • 你可以通过 AOP 或手动设置来决定何时使用主库或从库。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

圆咕噜咕噜

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表