雪花算法 YES/NO
This commit is contained in:
parent
8e07f8e7fd
commit
c07e7f48eb
|
|
@ -23,6 +23,11 @@ public class SpringContextUtils implements ApplicationContextAware {
|
||||||
return applicationContext.getBean(name);
|
return applicationContext.getBean(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object getSpringBean(Class<?> clazz) {
|
||||||
|
return applicationContext == null ? null : applicationContext.getBean(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static <T> T getBean(String name, Class<T> requiredType) {
|
public static <T> T getBean(String name, Class<T> requiredType) {
|
||||||
return applicationContext.getBean(name, requiredType);
|
return applicationContext.getBean(name, requiredType);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.sqx.config;
|
package com.sqx.config;
|
||||||
|
|
||||||
|
import com.sqx.modules.utils.InvitationCodeUtil;
|
||||||
import com.sqx.sharding.MasterSlaveRules;
|
import com.sqx.sharding.MasterSlaveRules;
|
||||||
import com.sqx.sharding.ShardingDataBase;
|
import com.sqx.sharding.ShardingDataBase;
|
||||||
import com.zaxxer.hikari.HikariConfig;
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
|
@ -8,10 +9,12 @@ import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
|
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
|
||||||
|
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
|
||||||
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
|
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
|
||||||
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
|
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.InlineShardingStrategyConfiguration;
|
||||||
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
|
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
|
||||||
|
import org.codehaus.groovy.util.StringUtil;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
@ -131,13 +134,32 @@ public class ShardingConfig {
|
||||||
String.format(centerTablesDataNode, centerTable));
|
String.format(centerTablesDataNode, centerTable));
|
||||||
sets.add(tableRuleConfig);
|
sets.add(tableRuleConfig);
|
||||||
}
|
}
|
||||||
|
//雪花算法方法
|
||||||
|
InvitationCodeUtil.getSnowFlakeId();
|
||||||
// 定义区域表的分库规则
|
// 定义区域表的分库规则
|
||||||
InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration(
|
InlineShardingStrategyConfiguration databaseShardingStrategyConfig = new InlineShardingStrategyConfiguration(
|
||||||
regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm);
|
regionTablesShardingDatabaseColumn, regionTablesShardingDatabaseAlgorithm);
|
||||||
for (String regionTable : regionTables) {
|
for (String regionTable : regionTables) {
|
||||||
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
|
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
|
||||||
tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig);
|
tableRuleConfig.setDatabaseShardingStrategyConfig(databaseShardingStrategyConfig);
|
||||||
|
// 设置区域表使用雪花算法生成主键
|
||||||
|
switch (regionTable){
|
||||||
|
case "orders":
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "orders_id"));
|
||||||
|
break;
|
||||||
|
case "course_collect":
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "course_collect_id"));
|
||||||
|
break;
|
||||||
|
case "course_user":
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "course_user_id"));
|
||||||
|
break;
|
||||||
|
case "tb_user":
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "user_id"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(new KeyGeneratorConfiguration("SNOWFLAKE", "id"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
sets.add(tableRuleConfig);
|
sets.add(tableRuleConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,6 +169,10 @@ public class ShardingConfig {
|
||||||
for (String regionTable : courseDetails) {
|
for (String regionTable : courseDetails) {
|
||||||
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
|
TableRuleConfiguration tableRuleConfig = new TableRuleConfiguration(regionTable, String.format(regionTablesDataNode, regionTable));
|
||||||
tableRuleConfig.setDatabaseShardingStrategyConfig(courseDetailsShardingStrategyConfig);
|
tableRuleConfig.setDatabaseShardingStrategyConfig(courseDetailsShardingStrategyConfig);
|
||||||
|
// 设置区域表使用雪花算法生成主键
|
||||||
|
KeyGeneratorConfiguration keyGeneratorConfig = new KeyGeneratorConfiguration("SNOWFLAKE", "id");
|
||||||
|
tableRuleConfig.setKeyGeneratorConfig(keyGeneratorConfig);
|
||||||
|
|
||||||
sets.add(tableRuleConfig);
|
sets.add(tableRuleConfig);
|
||||||
}
|
}
|
||||||
return sets;
|
return sets;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
package com.sqx.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述: Twitter的分布式自增ID雪花算法snowflake (Java版)
|
||||||
|
**/
|
||||||
|
public class SnowFlake {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 起始的时间戳
|
||||||
|
*/
|
||||||
|
private final static long START_STMP = 1480166465631L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每一部分占用的位数
|
||||||
|
*/
|
||||||
|
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
|
||||||
|
private final static long MACHINE_BIT = 5; //机器标识占用的位数
|
||||||
|
private final static long DATACENTER_BIT = 5;//数据中心占用的位数
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每一部分的最大值
|
||||||
|
*/
|
||||||
|
private final static long MAX_DATACENTER_NUM = ~(-1L << DATACENTER_BIT);
|
||||||
|
private final static long MAX_MACHINE_NUM = ~(-1L << MACHINE_BIT);
|
||||||
|
private final static long MAX_SEQUENCE = ~(-1L << SEQUENCE_BIT);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每一部分向左的位移
|
||||||
|
*/
|
||||||
|
private final static long MACHINE_LEFT = SEQUENCE_BIT;
|
||||||
|
private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
|
||||||
|
private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据中心
|
||||||
|
*/
|
||||||
|
private long datacenterId;
|
||||||
|
/**
|
||||||
|
* 机器标识
|
||||||
|
*/
|
||||||
|
private long machineId;
|
||||||
|
/**
|
||||||
|
* 代表了一毫秒内生成的多个id的最新序号
|
||||||
|
*/
|
||||||
|
private long sequence = 10000L;
|
||||||
|
/**
|
||||||
|
* 上一次时间戳
|
||||||
|
*/
|
||||||
|
private long lastStmp = -1L;
|
||||||
|
|
||||||
|
public SnowFlake() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SnowFlake(long datacenterId, long machineId) {
|
||||||
|
if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
|
||||||
|
throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
|
||||||
|
}
|
||||||
|
if (machineId > MAX_MACHINE_NUM || machineId < 0) {
|
||||||
|
throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
|
||||||
|
}
|
||||||
|
this.datacenterId = datacenterId;
|
||||||
|
this.machineId = machineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 产生下一个ID
|
||||||
|
*
|
||||||
|
* @param ifEvenNum 是否偶数 true 时间不连续全是偶数 时间连续 奇数偶数 false 时间不连续 奇偶都有 所以一般建议用false
|
||||||
|
*/
|
||||||
|
public synchronized long nextId(boolean ifEvenNum) {
|
||||||
|
long currStmp = getNewstmp();
|
||||||
|
if (currStmp < lastStmp) {
|
||||||
|
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 时间不连续出来全是偶数
|
||||||
|
*/
|
||||||
|
if (ifEvenNum) {
|
||||||
|
if (currStmp == lastStmp) {
|
||||||
|
//相同毫秒内,序列号自增
|
||||||
|
sequence = (sequence + 1) & MAX_SEQUENCE;
|
||||||
|
//同一毫秒的序列数已经达到最大
|
||||||
|
if (sequence == 0L) {
|
||||||
|
currStmp = getNextMill();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//不同毫秒内,序列号置为0
|
||||||
|
sequence = 0L;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//相同毫秒内,序列号自增
|
||||||
|
sequence = (sequence + 1) & MAX_SEQUENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastStmp = currStmp;
|
||||||
|
|
||||||
|
return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
|
||||||
|
| datacenterId << DATACENTER_LEFT //数据中心部分
|
||||||
|
| machineId << MACHINE_LEFT //机器标识部分
|
||||||
|
| sequence; //序列号部分
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getNextMill() {
|
||||||
|
long mill = getNewstmp();
|
||||||
|
while (mill <= lastStmp) {
|
||||||
|
mill = getNewstmp();
|
||||||
|
}
|
||||||
|
return mill;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getNewstmp() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.sqx.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class SnowFlakeConfig {
|
||||||
|
/**
|
||||||
|
* 数据中心
|
||||||
|
*/
|
||||||
|
@Value("${snowflake.datacenterId}")
|
||||||
|
private String datacenterId;
|
||||||
|
/**
|
||||||
|
* 机器标识
|
||||||
|
*/
|
||||||
|
@Value("${snowflake.machineId}")
|
||||||
|
private String machineId;
|
||||||
|
|
||||||
|
@Bean(name = "snowFlake")
|
||||||
|
public SnowFlake snowFlake() {
|
||||||
|
return new SnowFlake(Long.parseLong(datacenterId), Long.parseLong(machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
package com.sqx.modules.utils;
|
package com.sqx.modules.utils;
|
||||||
|
|
||||||
|
import com.sqx.common.utils.SpringContextUtils;
|
||||||
|
import com.sqx.config.SnowFlake;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邀请码生成解密工具类
|
* 邀请码生成解密工具类
|
||||||
*
|
*
|
||||||
|
|
@ -122,5 +127,8 @@ public class InvitationCodeUtil {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSnowFlakeId() {
|
||||||
|
return String.valueOf(((SnowFlake) Objects.requireNonNull(SpringContextUtils.getSpringBean(SnowFlake.class))).nextId(false));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -59,6 +59,11 @@ limit:
|
||||||
urlRate: 10 # 同一用户单url每秒限制次数
|
urlRate: 10 # 同一用户单url每秒限制次数
|
||||||
ipJumpLimit: 4 # 同一ip每分钟跳动次数
|
ipJumpLimit: 4 # 同一ip每分钟跳动次数
|
||||||
|
|
||||||
|
# 指定sharding-jdbc雪花算法的工作机器ID
|
||||||
|
snowflake:
|
||||||
|
datacenterId: 1
|
||||||
|
machineId: 3
|
||||||
|
|
||||||
spring:
|
spring:
|
||||||
main:
|
main:
|
||||||
allow-circular-references: true
|
allow-circular-references: true
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue