第十五章 短链服务-Murmur哈希算法封装组件
第1集 Guava框架里面的Murmur哈希算法测试
简介: Guava框架里面的Murmur哈希算法测试
- Guava框里里面自带Murmur算法
- 单元测试
@Test
public void testMurmurHash() {
for (int i = 0; i < 50; i++) {
int num1 = random.nextInt(1000000);
int num2 = random.nextInt(1000000);
int num3 = random.nextInt(1000000);
String originalUrl = num1 + "baidu+" + num2 + ".net" + num3;
long murmur3_32 = Hashing.murmur3_32().hashUnencodedChars(originalUrl).padToLong();
System.out.println("murmur3_32="+murmur3_32);
}
}
- CommonUtil工具类
/**
* murmur hash算法
* @param param
* @return
*/
public static long murmurHash32(String param){
long murmur32 = Hashing.murmur3_32().hashUnencodedChars(param).padToLong();
return murmur32;
}
第2集 短链生成组件ShortLinkComponent封装
简介: 短链生成组件ShortLinkComponent封装
- 创建短链组件类 ShortLinkComponent
/**
* 创建短链
* @param originalUrl
* @return db编码+6位短链编码
*/
public String createShortLinkCode(String originalUrl){
long murmur32 = CommonUtil.murmurHash32(originalUrl);
//转62进制
String shortLinkCode = encodeToBase62(murmur32);
return code;
}
- 10进制转62进制
private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/**
* 10进制转62进制
* @param num
* @return
*/
private static String encodeToBase62(long num) {
//StringBuffer:线程安全; StringBuilder:线程不安全
StringBuffer sb = new StringBuffer();
do {
int i = (int) (num % 62);
sb.append(CHARS.charAt(i));
num /= 62;
// num = num/ 62;
} while (num > 0);
String value = sb.reverse().toString();
return value;
}
第3集 组件ShortLinkComponent测试和疑惑解答
简介: 组件ShortLinkComponent测试和疑惑解答
- 单元测试
/**
* 测试短链平台
*/
@Test
public void testCreateShortLink() {
Random random = new Random();
for (int i = 0; i < 100; i++) {
int num1 = random.nextInt(10);
int num2 = random.nextInt(1000000);
int num3 = random.nextInt(1000000);
String originalUrl = num1 + "baidu" + num2 + ".net" + num3;
String shortLinkCode = shortLinkComponent.createShortLinkCode(originalUrl);
log.info("originalUrl:" + originalUrl + ", shortLinkCode=" + shortLinkCode);
}
}
- 为什么要用62进制转换,不是64进制?
- 62进制转换是因为62进制转换后只含数字+小写+大写字母
- 而64进制转换会含有/、+这样的符号(不符合正常URL的字符)
- 10进制转62进制可以缩短字符,如果我们要6位字符的话,已经有560亿个组合了
- 看业务情况有些短链也会加入其它特殊字符
- 短链固定6位?肯定不是的,后续会进行分库分表改造
第十六章 短链服务-数据库表建立和业务代码开发
第1集 数据库表模型讲解-短链分组和短链
简介: 数据库表模型讲解-短链分组和短链
-
关系
- 一个账号有多个分组
- 一个分组下有多个短链
-
短链-分组
CREATE TABLE `link_group` (
`id` bigint unsigned NOT NULL,
`title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '组名',
`account_no` bigint DEFAULT NULL COMMENT '账号唯一编号',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP,
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
- 短链
CREATE TABLE `short_link` (
`id` bigint unsigned NOT NULL ,
`group_id` bigint DEFAULT NULL COMMENT '组',
`title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '短链标题',
`original_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '原始url地址',
`domain` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '短链域名',
`code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '短链压缩码',
`sign` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '长链的md5码,方便查找',
`expired` datetime DEFAULT NULL COMMENT '过期时间,长久就是-1',
`account_no` bigint DEFAULT NULL COMMENT '账号唯一编号',
`gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`del` int unsigned NOT NULL COMMENT '0是默认,1是删除',
`state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '状态,lock是锁定不可用,active是可用',
`link_type` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '链接产品层级:FIRST 免费青铜、SECOND黄金、THIRD钻石',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
第2集 MybatisPlus逆向工具生成短链服务相关java对象
简介: MybatisPlus逆向工具生成短链服务相关java对象
- 配置代码
public class MyBatisPlusGenerator {
public static void main(String[] args) {
//1. 全局配置
GlobalConfig config = new GlobalConfig();
// 是否支持AR模式
config.setActiveRecord(true)
// 作者
.setAuthor("oop")
// 生成路径,最好使用绝对路径,window路径是不一样的
//TODO TODO TODO TODO
.setOutputDir("/Users/class/Desktop/demo/src/main/java")
// 文件覆盖
.setFileOverride(true)
// 主键策略
.setIdType(IdType.AUTO)
.setDateType(DateType.ONLY_DATE)
// 设置生成的service接口的名字的首字母是否为I,默认Service是以I开头的
.setServiceName("%sService")
//实体类结尾名称
.setEntityName("%sDO")
//生成基本的resultMap
.setBaseResultMap(true)
//不使用AR模式
.setActiveRecord(false)
//生成基本的SQL片段
.setBaseColumnList(true);
//2. 数据源配置
DataSourceConfig dsConfig = new DataSourceConfig();
// 设置数据库类型
dsConfig.setDbType(DbType.MYSQL)
.setDriverName("com.mysql.cj.jdbc.Driver")
//TODO TODO TODO TODO
.setUrl("jdbc:mysql://120.79.150.146:3306/dcloud_link?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai")
.setUsername("root")
.setPassword("xdclass.net168");
//3. 策略配置globalConfiguration中
StrategyConfig stConfig = new StrategyConfig();
//全局大写命名
stConfig.setCapitalMode(true)
// 数据库表映射到实体的命名策略
.setNaming(NamingStrategy.underline_to_camel)
//使用lombok
.setEntityLombokModel(true)
//使用restcontroller注解
.setRestControllerStyle(true)
// 生成的表, 支持多表一起生成,以数组形式填写
//TODO TODO TODO TODO
.setInclude("link_group","short_link");
//4. 包名策略配置
PackageConfig pkConfig = new PackageConfig();
pkConfig.setParent("net.class")
.setMapper("mapper")
.setService("service")
.setController("controller")
.setEntity("model")
.setXml("mapper");
//5. 整合配置
AutoGenerator ag = new AutoGenerator();
ag.setGlobalConfig(config)
.setDataSource(dsConfig)
.setStrategy(stConfig)
.setPackageInfo(pkConfig);
//6. 执行操作
ag.execute();
System.out.println("======= Done 相关代码生成完毕 ========");
}
}
- 导入生成好的代码
- model (为啥不放common项目,如果是确定每个服务都用到的依赖或者类才放到common项目)
- mapper 类接口拷贝
- resource/mapper文件夹 xml脚本拷贝
- controller
- service 不拷贝
第3集 遇到的坑-配置文件修改-yml转properties
简介: 配置文件修改-yml转properties
- SpringBoot的配置文件有两种
- 一种是properties结尾的
- 一种是yaml或者yml文件结尾的
- 如果同时存在properties和yml, application.properties里面的属性就会覆盖里application.yml的属性
- yml的注意点
- yml中缩进一定不能使用TAB,否则会报很奇怪的错误
- yml每个的冒号后面一定都要加一个空格
- 第一个是yml是支持中文内容的,properties想使用中文需要unicode编码
- 账号服务配置转换
- 在线转换工具:https://www.toyaml.com
server.port=8001
spring.application.name=dcloud-account
#----------服务注册和发现--------------
spring.cloud.nacos.discovery.server-addr=120.79.150.146:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
#-------redis连接配置-------
spring.redis.client-type=jedis
spring.redis.host=120.79.150.146
spring.redis.password=class.net
spring.redis.port=6379
spring.redis.jedis.pool.max-active=100
spring.redis.jedis.pool.max-idle=100
spring.redis.jedis.pool.min-idle=100
spring.redis.jedis.pool.max-wait=60000
#-------分库分表数据源配置-------
spring.shardingsphere.datasource.names=ds0
spring.shardingsphere.datasource.ds0.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_account?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds0.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds0.maxPoolSize=50
spring.shardingsphere.datasource.ds0.minPoolSize=50
spring.shardingsphere.datasource.ds0.password=class.net168
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.props.sql.show=true
# 指定traffic表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.traffic.actual-data-nodes=ds0.traffic_$->{0..1}
#水平分表策略+行表达式分片
spring.shardingsphere.sharding.tables.traffic.table-strategy.inline.algorithm-expression=traffic_$->{ account_no % 2 }
spring.shardingsphere.sharding.tables.traffic.table-strategy.inline.sharding-column=account_no
#id生成策略
spring.shardingsphere.sharding.tables.traffic.key-generator.column=id
spring.shardingsphere.sharding.tables.traffic.key-generator.props.worker.id=${workId}
spring.shardingsphere.sharding.tables.traffic.key-generator.type=SNOWFLAKE
#----------sms短信配置--------------
sms.app-code=6999d4df3e7d48028470bbe517169a8d
sms.template-id=M72CB42894
#----------阿里云OSS配置--------------
aliyun.oss.endpoint=oss-cn-guangzhou.aliyuncs.com
aliyun.oss.access-key-id=LTAI5tHVGvYw7twoVFyruB1H
aliyun.oss.access-key-secret=r4d0EudzSvPfVMb9Zp0TfmsE32RXmN
aliyun.oss.bucketname=dcloud-link
- 短链服务相关配置文件(复制账号微服务配置修改)
第4集 短链分组管理-CURD接口开发实战《上》
简介: 短链分组管理-CURD接口开发实战《上》
- 配置登录拦截器
- 新增接口
- 删除接口
第5集 短链分组管理-CURD接口开发实战《下》
简介: 短链分组管理-CURD接口开发实战《下》
- 查询详情
- 查询用户全部分组
- 更新分组接口
第6集 短链分组管理-水平分库分表配置实战《青铜玩法》
简介: 短链分组管理-水平分库分表配置实战
- 需求
- 未来2年,短链平台累计5百万用户
- 短链组:一个用户30个组,就是1.5亿个组
- 单表不超过1千万数据,需要分15张表
- 进一步延伸,进行水平分库分表,比如 2库、4库、8库、16库
- 一个库一张表
- 需要降低单表数据量,进行水平分库分表
- 分库数量:线上分16库,本地分2库即可
- 分片key: account_no,查询维度都是根据account_no进行查询
- 分片策略:行表达式分片策略 InlineShardingStrategy
- 未来2年,短链平台累计5百万用户
- 配置
#----------短链组,策略:水平分库,不水平分表--------------
# 先进行水平分库, 水平分库策略,行表达式分片
spring.shardingsphere.sharding.tables.link_group.database-strategy.inline.sharding-column=account_no
spring.shardingsphere.sharding.tables.link_group.database-strategy.inline.algorithm-expression=ds$->{account_no % 2}
第十七章 短链服务分库分表-如何做到扩容免数据迁移《黄金玩法》
第1集 短链服务-ShortLink分库分表解决方案讲解《青铜》
简介: 短链服务-ShortLink分库分表解决方案讲解
-
-
数据量预估
- 首年日活用户: 10万
- 首年日新增短链数据:10万*50 = 500万
- 年新增短链数:500万 * 365天 = 18.2亿
- 往高的算就是100亿,支撑3年
-
分库分表策略
-
分库分表
- 16个库, 每个库64个表,总量就是 1024个表
-
分片键:短链码 code
- 比如 g1.fit/92AEva 的短链码 92AEva
-
分库分表算法:短链码进行hash取模
库ID = 短链码hash值 % 库数量 表ID = 短链码hash值 / 库数量 % 表数量
-
-
-
优点
- 保证数据较均匀的分散落在不同的库、表中,可以有效的避免热点数据集中问题,
- 分库分表方式清晰易懂
-
问题
- 扩容不是很方便,需要数据迁移
- 需要一次性建立16个库, 每个库64个表,总量就是 1024个表,浪费资源
第2集 短链服务-分库分表扩容免数据迁移解决方案讲解《黄金玩法》
简介: 短链服务-分库分表免迁移扩容解决方案讲解《黄金玩法》
-
需要解决的问题
-
数据量增加,扩容避免迁移数据或者免迁移
-
前期数据量不多,不浪费库表系统资源
- 分库分表:16个库, 每个库64个表,总量就是 1024个表
-
-
短链码
- 比如 g1.fit/92AEva 的短链码 92AEva
-
如何做?
- 从短链码入手-增加库表位
- 类似案例-阿里这边商品订单号-里面也包括了库表信息
第3集 短链服务-分库分表相关库表建立
简介: 短链服务-分库分表相关库表建立
-
为啥能做到免迁移扩容?
- A92AEva1
- 由于短链码的前缀和后缀是是固定的,所以扩容也不影响旧的数据
- 类似的免迁移扩容策略还有哪些?
- 时间范围分库分表
- id范围分库分表
-
三个库
-
一个库两个表
-
properties配置多库表
spring.shardingsphere.datasource.names=ds0,ds1,dsa
#ds0配置
spring.shardingsphere.datasource.ds0.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds0.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds0.maxPoolSize=50
spring.shardingsphere.datasource.ds0.minPoolSize=50
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=class.net168
#ds1配置
spring.shardingsphere.datasource.ds1.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.ds1.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.ds1.maxPoolSize=50
spring.shardingsphere.datasource.ds1.minPoolSize=50
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=class.net168
#dsa配置
spring.shardingsphere.datasource.dsa.connectionTimeoutMilliseconds=30000
spring.shardingsphere.datasource.dsa.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.dsa.idleTimeoutMilliseconds=60000
spring.shardingsphere.datasource.dsa.jdbc-url=jdbc:mysql://120.79.150.146:3306/dcloud_link_a?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.dsa.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.dsa.maintenanceIntervalMilliseconds=30000
spring.shardingsphere.datasource.dsa.maxLifetimeMilliseconds=1800000
spring.shardingsphere.datasource.dsa.maxPoolSize=50
spring.shardingsphere.datasource.dsa.minPoolSize=50
spring.shardingsphere.datasource.dsa.username=root
spring.shardingsphere.datasource.dsa.password=class.net168
第4集 短链服务水平分库分表实战-标准分片策略-精准分片算法《上》
简介: 短链服务分库分表实战-标准分片策略-精准分片算法
- 水平分库-标准分片策略-精准分片算法 Ae23asa1
public class CustomDBPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
/**
* @param availableTargetNames 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param shardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
//获取短链码第一位,即库位
String codePrefix = shardingValue.getValue().substring(0, 1);
for (String targetName : availableTargetNames) {
//获取库名的最后一位,真实配置的ds
String targetNameSuffix = targetName.substring(targetName.length() - 1);
//如果一致则返回
if (codePrefix.equals(targetNameSuffix)) {
return targetName;
}
}
//抛异常
throw new BizException(BizCodeEnum.DB_ROUTE_NOT_FOUND);
}
}
- 配置
#----------短链,策略:分库+分表--------------
# 先进行水平分库,然后再水平分表
spring.shardingsphere.sharding.tables.short_link.database-strategy.standard.sharding-column=code
spring.shardingsphere.sharding.tables.short_link.database-strategy.standard.precise-algorithm-class-name=net.class.strategy.CustomDBPreciseShardingAlgorithm
第5集 短链服务水平分库分表实战-标准分片策略-精准分片算法《下》
简介: 短链服务分库分表实战-标准分片策略-精准分片算法
- 水平分表-标准分片策略-精准分片算法
public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
/**
* @param availableTargetNames 数据源集合
* 在分库时值为所有分片库的集合 databaseNames
* 分表时为对应分片库中所有分片表的集合 tablesNames
* @param shardingValue 分片属性,包括
* logicTableName 为逻辑表,
* columnName 分片健(字段),
* value 为从 SQL 中解析出的分片健的值
* @return
*/
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
//获取逻辑表名
String targetName = availableTargetNames.iterator().next();
String value = shardingValue.getValue();
//短链码最后一位
String codePrefix = value.substring(value.length()-1);
//拼装actual table
return targetName + "_" + codePrefix;
}
}
- 配置文件
# 水平分表策略,自定义策略。 真实库.逻辑表
spring.shardingsphere.sharding.tables.short_link.actual-data-nodes=ds0.short_link,ds1.short_link,dsa.short_link
spring.shardingsphere.sharding.tables.short_link.table-strategy.standard.sharding-column=code
spring.shardingsphere.sharding.tables.short_link.table-strategy.standard.precise-algorithm-class-name=net.class.strategy.CustomTablePreciseShardingAlgorithm
#id生成策略
spring.shardingsphere.sharding.tables.short_link.key-generator.column=id
spring.shardingsphere.sharding.tables.short_link.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.short_link.key-generator.props.worker.id=${workerId}
第6集 短链服务-短链码配置生成库表位实战
简介: 短链服务-短链码配置生成库表位实战
- 分库位
public class ShardingDBConfig {
/**
* 存储数据库位置编号
*/
private static final List<String> dbPrefixList = new ArrayList<>();
private static Random random = new Random();
//配置启用那些库的前缀
static {
dbPrefixList.add("0");
dbPrefixList.add("1");
dbPrefixList.add("a");
}
/**
* 获取随机的前缀
* @return
*/
public static String getRandomDBPrefix(){
int index = random.nextInt(dbPrefixList.size());
return dbPrefixList.get(index);
}
}
- 分表位
public class ShardingTableConfig {
/**
* 存储数据表位置编号
*/
private static final List<String> tableSuffixList = new ArrayList<>();
private static Random random = new Random();
//配置启用那些表的后缀
static {
tableSuffixList.add("0");
tableSuffixList.add("a");
}
/**
* 获取随机的后缀
* @return
*/
public static String getRandomTableSuffix(){
int index = random.nextInt(tableSuffixList.size());
return tableSuffixList.get(index);
}
}
- 短链码配置
String code = ShardingDBConfig.getRandomDBPrefix() + shortLinkCode + ShardingTableConfig.getRandomTablePrefix();
第7集 短链服务-Manager层模块CRUD开发
简介: 短链服务-Manager层模块CRUD开发
- 代码
public interface ShortLinkManager {
/**
* 新增域名
*
* @param shortLinkDO
* @return
*/
int addShortLink(ShortLinkDO shortLinkDO);
/**
* 根据短链码找内容
*
* @param shortLinkCode
* @return
*/
ShortLinkDO findByShortLinkCode(String shortLinkCode);
/**
* 根据短链码和accountNo删除
*
* @param shortLinkCode
* @param accountNo
* @return
*/
int del(String shortLinkCode, Long accountNo);
}
@Component
@Slf4j
public class ShortLinkManagerImpl implements ShortLinkManager {
@Autowired
private ShortLinkMapper shortLinkMapper;
@Override
public int addShortLink(ShortLinkDO shortLinkDO) {
return shortLinkMapper.insert(shortLinkDO);
}
@Override
public ShortLinkDO findByShortLinkCode(String shortLinkCode) {
ShortLinkDO shortLinkDO = shortLinkMapper.selectOne(new QueryWrapper<ShortLinkDO>().eq("code", shortLinkCode).eq("del", 0));
return shortLinkDO;
}
/**
* 逻辑删除
*
* @param shortLinkCode
* @param accountNo
* @return
*/
@Override
public int del(String shortLinkCode, Long accountNo) {
ShortLinkDO shortLinkDO = new ShortLinkDO();
shortLinkDO.setDel(1);
int rows = shortLinkMapper.update(shortLinkDO, new QueryWrapper<ShortLinkDO>()
.eq("code", shortLinkCode).eq("account_no", accountNo));
return rows;
}
}
第8集 短链服务-自定义分库分表策略单元测试实战
简介: 短链服务-自定义分库分表策略单元测试实战
-
单元测试
- 保存
@Autowired private ShortLinkManager shortLinkManager; /** * 保存 */ @Test public void testSaveShortLink() { Random random = new Random(); //for (int i = 0; i < 10; i++) { int num1 = random.nextInt(10); int num2 = random.nextInt(10000000); int num3 = random.nextInt(10000000); String originalUrl = num1 + "class" + num2 + ".net" + num3; String shortLinkCode = shortLinkComponent.createShortLinkCode(originalUrl); ShortLinkDO shortLinkDO = new ShortLinkDO(); shortLinkDO.setCode(shortLinkCode); shortLinkDO.setAccountNo(Long.valueOf(num3)); shortLinkDO.setSign(originalUrl); shortLinkDO.setDel(0); shortLinkManager.addShortLink(shortLinkDO); //} }
- 查找
@Test public void testFind() { ShortLinkDO shortLinkDO = shortLinkManager.findByShortLinkCode("03aAg0la"); log.info(shortLinkDO.toString()); }
第9集 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案
简介: 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案
- 问题
- 假如前期分三个库,一个库两个表,项目火爆,数据量激增,进行扩容
- 增加了新的数据库表位,会导致旧的库表比新的库表数据量多,且容易出现超载情况
Nginx加权负载均衡的应用
-
不同的库表位分配的概率不一样,类似的中间件应用场景有nginx
-
Nginx常见的负载均衡策略
-
节点轮询(默认)
-
weight 权重配置
- 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
- 场景:服务器性能差异大的情况使用
upstream lbs { server 192.168.159.133:8080 weight=5; server 192.168.159.133:8081 weight=10; }
-
-
加权解决方式(作业)
- 库表位可以使用对象形式,配置权重,避免数据倾斜、数据集中
- 编写算法,根据不同的,配置权重,不同的库表位配置不同的权重
- 加权配置,list重复添加出现的高频的库表位
-
是不是可以把这个亮点记录下
- 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题
- 业务量超过评估量,分库分表-二次扩容的时候避免数据迁移
- 不用一次性建立很多个库表,可以动态添加,节省服务器资源
- 使用加权库表位算法,解决扩容后数据倾斜不均匀问题
kDO = shortLinkManager.findByShortLinkCode(“03aAg0la”);
log.info(shortLinkDO.toString());
}
- 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题
第9集 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案
简介: 加权负载均衡思想应用-数据库表扩容-数据不均匀问题解决方案
- 问题
- 假如前期分三个库,一个库两个表,项目火爆,数据量激增,进行扩容
- 增加了新的数据库表位,会导致旧的库表比新的库表数据量多,且容易出现超载情况
[外链图片转存中…(img-rjjMnBdI-1722993581899)]
Nginx加权负载均衡的应用
-
不同的库表位分配的概率不一样,类似的中间件应用场景有nginx
-
Nginx常见的负载均衡策略
-
节点轮询(默认)
-
weight 权重配置
- 简介:weight和访问比率成正比,数字越大,分配得到的流量越高
- 场景:服务器性能差异大的情况使用
upstream lbs { server 192.168.159.133:8080 weight=5; server 192.168.159.133:8081 weight=10; }
-
[外链图片转存中…(img-XmNbwxWe-1722993581899)]
-
加权解决方式(作业)
- 库表位可以使用对象形式,配置权重,避免数据倾斜、数据集中
- 编写算法,根据不同的,配置权重,不同的库表位配置不同的权重
- 加权配置,list重复添加出现的高频的库表位
-
是不是可以把这个亮点记录下
- 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题
- 业务量超过评估量,分库分表-二次扩容的时候避免数据迁移
- 不用一次性建立很多个库表,可以动态添加,节省服务器资源
- 使用加权库表位算法,解决扩容后数据倾斜不均匀问题
- 你想到的解决方案,方便又清晰,还省服务器资源和避免了问题