视频056~(完成雪花算法)

master
Administrator 3 years ago
parent 432d5464cb
commit 3d5d86584b

@ -4,6 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;
/**
* @author zjw
@ -12,6 +13,10 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@ComponentScan(basePackages = {
"com.mashibing.api",
"com.mashibing.common"
})
public class ApiStarterApp {
public static void main(String[] args) {

@ -6,6 +6,7 @@ import com.mashibing.api.util.R;
import com.mashibing.api.vo.ResultVO;
import com.mashibing.common.enums.ExceptionEnums;
import com.mashibing.common.model.StandardSubmit;
import com.mashibing.common.util.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -30,6 +31,10 @@ import javax.servlet.http.HttpServletRequest;
@RefreshScope
public class SmsController {
@Autowired
private SnowFlakeUtil snowFlakeUtil;
/**
* IP','
*/
@ -80,6 +85,9 @@ public class SmsController {
//=========================调用策略模式的校验链=========================================
checkFilterContext.check(submit);
//========================基于雪花算法生成唯一id并添加到StandardSubmit对象中=========================================
submit.setSequenceId(snowFlakeUtil.nextId());
//=========================发送到MQ交给策略模块处理=========================================
return R.ok();
}

@ -16,7 +16,8 @@ public enum ExceptionEnums {
ERROR_MOBILE(-5,"手机号格式不正确"),
BALANCE_NOT_ENOUGH(-6,"客户余额不足"),
PARAMETER_ERROR(-10,"参数不合法!"),
SNOWFLAKE_OUT_OF_RANGE(-11,"雪花算法的机器id或服务id超出最大范围")
SNOWFLAKE_OUT_OF_RANGE(-11,"雪花算法的机器id或服务id超出最大范围"),
SNOWFLAKE_TIME_BACK(-12,"雪花算法的服务器出现时间回拨问题!"),
;
private Integer code;

@ -2,15 +2,10 @@ package com.mashibing.common.util;
import com.mashibing.common.enums.ExceptionEnums;
import com.mashibing.common.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
/**
* ID
@ -24,7 +19,6 @@ import java.util.Date;
* @description
*/
@Component
@Slf4j
public class SnowFlakeUtil {
/**
@ -98,16 +92,64 @@ public class SnowFlakeUtil {
/**
*
*/
private long timestampShift = sequenceBits + serviceIdBits + maxMachineId;
private long timestampShift = sequenceBits + serviceIdBits + machineIdBits;
/**
*
*/
private long maxSequenceId = -1 ^ (-1 << sequenceBits);
/**
* id
*/
private long lastTimestamp = -1;
/**
*
* @return
*/
private long timeGen(){
return System.currentTimeMillis();
}
public synchronized long nextId(){
//1、 拿到当前系统时间的毫秒值
long timestamp = timeGen();
// 避免时间回拨造成出现重复的id
if(timestamp < lastTimestamp){
// 说明出现了时间回拨
System.out.println("当前服务出现时间回拨!!!");
throw new ApiException(ExceptionEnums.SNOWFLAKE_TIME_BACK);
}
//2、 判断当前生成id的时间和上一次生成的时间
if(timestamp == lastTimestamp){
// 同一毫秒值生成id
sequence = (sequence + 1) & maxSequenceId;
// 0000 10100000 :sequence
// 1111 11111111 :maxSequenceId
if(sequence == 0){
// 进到这个if说明已经超出了sequence序列的最大取值范围
// 需要等到下一个毫秒再做回来生成具体的值
timestamp = timeGen();
while(timestamp <= lastTimestamp){
// 时间还没动。
timestamp = timeGen();
}
}
}else{
// 另一个时间点生成id
sequence = 0;
}
//3、重新给lastTimestamp复制
lastTimestamp = timestamp;
//4、计算id将几位值拼接起来。 41bit位的时间5位的机器5位的服务 12位的序列
return ((timestamp - timeStart) << timestampShift) |
(machineId << machineIdShift) |
(serviceId << serviceIdShift) |
sequence &
Long.MAX_VALUE;
}
}

Loading…
Cancel
Save