赞
踩
分布式项目在通过一定的服务拆分,项目运行一段时间以后,随着用户和使用资源的不断增大,数据库的性能也会面临瓶颈。单表数据量过大,超高并发的读写引发的锁问题,导致系统运行加载越来越慢,不时出现系统假死的现象,数据库的优化已将近极限,几乎没有空间,这时就需要考虑读写分离,分库分表(这里主要是水平的分库分表)的策略,来减少对同一数据库的访问的压力。
application.yml
-
- spring:
- shardingsphere:
- datasource:
- names: master,slave
- #数据源配置
- master:
- driver-class-name: com.mysql.jdbc.Driver
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://localhost:3306/master0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
- username: root
- password: 123456
- slave:
- driver-class-name: com.mysql.jdbc.Driver
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://localhost:3306/slave0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
- username: root
- password: 123456
-
- #读写分离配置(主库写,从库读)
- masterslave:
- load-balance-algorithm-type: round_robin
- name: ms
- #写库
- master-data-source-name: master
- #读库
- slave-data-source-names: slave
- props:
- sql:
- show: true
- main:
- allow-bean-definition-overriding: true
-
-
- package com.aliyun.readWrite.test.controller;
-
-
- import com.aliyun.readWrite.test.entity.VideoRoom;
- import com.aliyun.readWrite.test.service.IVideoRoomService;
- import com.aliyun.util.Result;
- import com.aliyun.util.StatusCode;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- /**
- * <p>
- * 房间表 前端控制器
- * </p>
- *
- * @author haige
- * @since 2021-11-24
- */
-
- @Slf4j
- @RestController
- @RequestMapping("/videoRoom")
- public class VideoRoomController {
-
- @Autowired
- public IVideoRoomService videoRoomService;
-
- @PostMapping("/save")
- public Result save(@RequestBody VideoRoom videoRoom){
- videoRoomService.save(videoRoom);
- return new Result(StatusCode.SUCCESS,"保存成功");
- }
-
- @GetMapping("/get/{id}")
- public Result get(@PathVariable("id") String id){
- VideoRoom videoRoom = videoRoomService.getById(id);
- return new Result(StatusCode.SUCCESS,"查询成功",videoRoom);
- }
-
- }
-
-
实现了接口调用时master库写,slave库读的效果
application.yml
- spring:
- shardingsphere:
- props:
- sql:
- show: true
- main:
- allow-bean-definition-overriding: true
- datasource:
- names: master0,master1
- #数据源配置
- master0:
- driver-class-name: com.mysql.jdbc.Driver
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://localhost:3306/master0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
- username: root
- password: 123456
- master1:
- driver-class-name: com.mysql.jdbc.Driver
- type: com.alibaba.druid.pool.DruidDataSource
- url: jdbc:mysql://localhost:3306/master1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
- username: root
- password: 123456
-
- #分库分表配置
- sharding:
- #分库
- default-database-strategy:
- inline:
- sharding-column: age
- algorithm-expression: master$->{age % 2} #根据年龄分库
- #分表
- tables:
- tab_user:
- actual-data-nodes: master$->{0..1}.tab_user$->{0..1}
- table-strategy:
- inline:
- sharding-column: id
- algorithm-expression: tab_user$->{id % 2}
- package com.aliyun.config;
-
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
- import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
- import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
- import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
- import org.mybatis.spring.SqlSessionFactoryBean;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ComponentScan;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
-
- import javax.sql.DataSource;
- import java.sql.SQLException;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Properties;
-
- @Configuration
- @ComponentScan(basePackageClasses = DataSourceConfig.class)
- @MapperScan(basePackages = "com.aliyun.shard.mapper")
- public class DataSourceConfig {
-
- /**
- * SqlSessionFactory注入
- */
- @Bean
- public SqlSessionFactory sqlSessionFactory() throws Exception {
- PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
- SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
- sessionFactory.setDataSource(dataSource());
- sessionFactory.setFailFast(true);
- sessionFactory.setMapperLocations(resolver.getResources("classpath:/mapper/system/*Mapper.xml"));
- return sessionFactory.getObject();
- }
-
- @Bean
- public DataSource dataSource() throws SQLException {
- ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
- shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
- shardingRuleConfig.getBindingTableGroups().add("tab_user");
- // shardingRuleConfig.getBroadcastTables().add("t_config");
- //TODO 根据年龄分库 一共分为2个库
- shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("age", "master${age % 2}"));
- //TODO 根据ID分表 一共分为2张表
- shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", new PreciseModuloShardingTableAlgorithm()));
- return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new Properties());
- }
-
- private static KeyGeneratorConfiguration getKeyGeneratorConfiguration() {
- KeyGeneratorConfiguration result = new KeyGeneratorConfiguration("SNOWFLAKE", "id");
- return result;
- }
-
- TableRuleConfiguration getOrderTableRuleConfiguration() {
- TableRuleConfiguration result = new TableRuleConfiguration("tab_user", "master${0..1}.tab_user${0..1}");
- result.setKeyGeneratorConfig(getKeyGeneratorConfiguration());
- return result;
- }
-
-
- Map<String, DataSource> createDataSourceMap() {
- Map<String, DataSource> result = new HashMap<>();
- result.put("master0", DataSourceUtil.createDataSource("master0"));
- result.put("master1", DataSourceUtil.createDataSource("master1"));
- return result;
- }
- }
- package com.aliyun.config;
-
- import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
- import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
-
- import java.util.Collection;
-
- /**
- * 表分片规则
- */
- public final class PreciseModuloShardingTableAlgorithm implements PreciseShardingAlgorithm<Long> {
-
- @Override
- public String doSharding(final Collection<String> tableNames, final PreciseShardingValue<Long> shardingValue) {
- for (String each : tableNames) {
- if (each.endsWith(shardingValue.getValue() % 2 + "")) {
- return each;
- }
- }
- throw new UnsupportedOperationException();
- }
- }
- package com.aliyun.config;
-
- import com.alibaba.druid.pool.DruidDataSource;
-
- import javax.sql.DataSource;
-
- /**
- * @Description: 数据源配置
- *
- * @author xub
- * @date 2019/10/16 下午7:47
- */
- public final class DataSourceUtil {
-
- private static final String HOST = "localhost";
-
- private static final int PORT = 3306;
-
- private static final String USER_NAME = "root";
-
- private static final String PASSWORD = "123456";
-
- public static DataSource createDataSource(final String dataSourceName) {
- DruidDataSource result = new DruidDataSource();
- result.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
- result.setUrl(String.format("jdbc:mysql://%s:%s/%s?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8", HOST, PORT, dataSourceName));
- result.setUsername(USER_NAME);
- result.setPassword(PASSWORD);
- return result;
- }
- }
- package com.aliyun.shard.controller;
-
- import com.aliyun.shard.entity.TabUser;
- import com.aliyun.shard.service.ITabUserService;
- import com.aliyun.util.Result;
- import com.aliyun.util.StatusCode;
- import com.google.common.collect.Lists;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.annotation.PostConstruct;
- import java.util.List;
-
- /**
- * <p>
- * 前端控制器
- * </p>
- *
- * @author haige
- * @since 2021-11-26
- */
-
- @Slf4j
- @RestController
- @RequestMapping("/tabUser")
- public class TabUserController {
-
- @Autowired
- public ITabUserService tabUserService;
-
- /**
- * 模拟插入数据
- */
- List<TabUser> userList = Lists.newArrayList();
-
- /**
- * 初始化插入数据
- */
- @PostConstruct
- private void getData() {
- userList.add(new TabUser(1L,"小小", "女", 3));
- userList.add(new TabUser(2L,"爸爸", "男", 30));
- userList.add(new TabUser(3L,"妈妈", "女", 28));
- userList.add(new TabUser(4L,"爷爷", "男", 64));
- userList.add(new TabUser(5L,"奶奶", "女", 62));
- }
-
- @PostMapping("batchSaveUser")
- public Result batchSaveUser() {
- return new Result(StatusCode.SUCCESS,tabUserService.insertForEach(userList));
- }
-
- @GetMapping("/findAll")
- public Result findAll(){
- List<TabUser> tabUserList = tabUserService.findAll();
- return new Result(StatusCode.SUCCESS,"查询成功",tabUserList);
- }
-
- }
实现了5条数据分别添加到了tab_user0,tab_user1,tab_user2三张表,在查询findAll数据时又能返回三张表的所有数据。
感兴趣的猿友可以了解--> 下载源码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。