主键生成策略调整,日志部分调整

yun-zuoyi
alwaysfrin 6 years ago
parent b8a1196a45
commit 989ad48653

@ -0,0 +1,110 @@
package cn.estsh.i3plus.pojo.base.codemaker;
/**
* @Description :
* @Reference :
* @Author : alwaysfrin
* @CreateDate : 2019-01-10 13:11
* @Modify:
**/
@Deprecated
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 ^ (-1L << DATACENTER_BIT);
private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
private final static long MAX_SEQUENCE = -1L ^ (-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; // 机器标识
private long sequence = 0L; // 序列号
private long lastStmp = -1L;// 上一次时间戳
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
public synchronized long nextId() {
long currStmp = getNewstmp();
if (currStmp < lastStmp) {
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
}
if (currStmp == lastStmp) {
//if条件里表示当前调用和上一次调用落在了相同毫秒内只能通过第三部分序列号自增来判断为唯一所以+1.
sequence = (sequence + 1) & MAX_SEQUENCE;
//同一毫秒的序列数已经达到最大,只能等待下一个毫秒
if (sequence == 0L) {
currStmp = getNextMill();
}
} else {
//不同毫秒内序列号置为0
//执行到这个分支的前提是currTimestamp > lastTimestamp说明本次调用跟上次调用对比已经不再同一个毫秒内了这个时候序号可以重新回置0了。
sequence = 0L;
}
lastStmp = currStmp;
//就是用相对毫秒数、机器ID和自增序号拼接
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();
}
/** 测试 */
public static void main(String[] args) {
SnowFlake idWorker = new SnowFlake(0, 0);
for (int i = 0; i < 100; i++) {
long id = idWorker.nextId();
//System.out.println(Long.toBinaryString(id));
System.out.println(id);
}
Runnable testRun = new Runnable() {
@Override
public void run() {
SnowFlake idWorker = new SnowFlake(0, 0);
for (int i = 0; i < 10; i++) {
System.out.println(idWorker.nextId());
}
}
};
Thread thread1 = new Thread(testRun);
thread1.start();
Thread thread2 = new Thread(testRun);
thread2.start();
Thread thread3 = new Thread(testRun);
thread3.start();
Thread thread4 = new Thread(testRun);
thread4.start();
Thread thread5 = new Thread(testRun);
thread5.start();
}
}

@ -0,0 +1,123 @@
package cn.estsh.i3plus.pojo.base.codemaker;
/**
* @Description :
* @Reference :
* @Author : alwaysfrin
* @CreateDate : 2019-01-10 13:27
* @Modify:
**/
@Deprecated
public class SnowflakeId {
private long workerId;
private long datacenterId;
private long sequence = 0L;
public SnowflakeId(){
this.workerId = 1;
this.datacenterId = 1;
this.sequence = 0L;
}
public SnowflakeId(long workerId, long datacenterId){
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
private long twepoch = 1288834974657L;
private long workerIdBits = 5L;
private long datacenterIdBits = 5L;
private long maxWorkerId = -1L ^ (-1L << workerIdBits);
private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
private long sequenceBits = 12L;
private long workerIdShift = sequenceBits;
private long datacenterIdShift = sequenceBits + workerIdBits;
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private long sequenceMask = -1L ^ (-1L << sequenceBits);
private long lastTimestamp = -1L;
private long getWorkerId(){
return workerId;
}
private long getDatacenterId(){
return datacenterId;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp);
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
lastTimestamp - timestamp));
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}
lastTimestamp = timestamp;
return ((timestamp - twepoch) << timestampLeftShift) |
(datacenterId << datacenterIdShift) |
(workerId << workerIdShift) |
sequence;
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen(){
return System.currentTimeMillis();
}
//---------------测试---------------
public static void main(String[] args) {
SnowflakeId worker = new SnowflakeId();
Runnable testRun = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(i + "=" + worker.nextId());
}
}
};
Thread thread1 = new Thread(testRun);
thread1.start();
Thread thread2 = new Thread(testRun);
thread2.start();
Thread thread3 = new Thread(testRun);
thread3.start();
Thread thread4 = new Thread(testRun);
thread4.start();
Thread thread5 = new Thread(testRun);
thread5.start();
System.out.println(new SnowflakeId().nextId());
for (int i = 0; i < 10; i++) {
//System.out.println(worker.nextId());
}
}
}

@ -10,30 +10,27 @@ package cn.estsh.i3plus.pojo.base.codemaker;
* @Modify:
**/
public class SnowflakeIdMaker {
private long workerId;
private long datacenterId;
private long sequence;
private long sequence = 0L;
public SnowflakeIdMaker(){
this.workerId = 1;
this.datacenterId = 1;
this.sequence = 1;
this.sequence = 0L;
}
public SnowflakeIdMaker(long workerId, long datacenterId, long sequence){
// sanity check for workerId
public SnowflakeIdMaker(long workerId, long datacenterId){
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",maxDatacenterId));
}
// System.out.printf("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",
// timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);
this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = sequence;
}
private long twepoch = 1288834974657L;
@ -59,10 +56,6 @@ public class SnowflakeIdMaker {
return datacenterId;
}
private long getTimestamp(){
return System.currentTimeMillis();
}
public synchronized long nextId() {
long timestamp = timeGen();
@ -102,13 +95,26 @@ public class SnowflakeIdMaker {
//---------------测试---------------
public static void main(String[] args) {
System.out.println(new SnowflakeIdMaker().nextId());
SnowflakeIdMaker worker = new SnowflakeIdMaker();
for (int i = 0; i < 10; i++) {
System.out.println(worker.nextId());
}
Runnable testRun = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(worker.nextId());
}
}
};
Thread thread1 = new Thread(testRun);
thread1.start();
Thread thread2 = new Thread(testRun);
thread2.start();
Thread thread3 = new Thread(testRun);
thread3.start();
Thread thread4 = new Thread(testRun);
thread4.start();
Thread thread5 = new Thread(testRun);
thread5.start();
worker = new SnowflakeIdMaker(1,1,1);
for (int i = 0; i < 10; i++) {
System.out.println(worker.nextId());
}

@ -0,0 +1,161 @@
package cn.estsh.i3plus.pojo.base.codemaker;
/**
* @Description :
* @Reference :
* @Author : alwaysfrin
* @CreateDate : 2019-01-10 13:07
* @Modify:
**/
@Deprecated
public class SnowflakeIdWorker {
/** 开始时间截 (2015-01-01) */
private final long twepoch = 1420041600000L;
/** 机器id所占的位数 */
private final long workerIdBits = 5L;
/** 数据标识id所占的位数 */
private final long datacenterIdBits = 5L;
/** 支持的最大机器id结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
/** 支持的最大数据标识id结果是31 */
private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
/** 序列在id中占的位数 */
private final long sequenceBits = 12L;
/** 机器ID向左移12位 */
private final long workerIdShift = sequenceBits;
/** 数据标识id向左移17位(12+5) */
private final long datacenterIdShift = sequenceBits + workerIdBits;
/** 时间截向左移22位(5+5+12) */
private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
/** 生成序列的掩码这里为4095 (0b111111111111=0xfff=4095) */
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
/** 工作机器ID(0~31) */
private long workerId;
/** 数据中心ID(0~31) */
private long datacenterId;
/** 毫秒内序列(0~4095) */
private long sequence = 0L;
/** 上次生成ID的时间截 */
private long lastTimestamp = -1L;
//==============================Constructors=====================================
/**
*
* @param workerId ID (0~31)
* @param datacenterId ID (0~31)
*/
public SnowflakeIdWorker(long workerId, long datacenterId) {
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
// ==============================Methods==========================================
/**
* ID (线)
* @return SnowflakeId
*/
public synchronized long nextId() {
long timestamp = timeGen();
//如果当前时间小于上一次ID生成的时间戳说明系统时钟回退过这个时候应当抛出异常
if (timestamp < lastTimestamp) {
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}
//如果是同一时间生成的,则进行毫秒内序列
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
//毫秒内序列溢出
if (sequence == 0) {
//阻塞到下一个毫秒,获得新的时间戳
timestamp = tilNextMillis(lastTimestamp);
}
}
//时间戳改变,毫秒内序列重置
else {
sequence = 0L;
}
//上次生成ID的时间截
lastTimestamp = timestamp;
//移位并通过或运算拼到一起组成64位的ID
return ((timestamp - twepoch) << timestampLeftShift) //
| (datacenterId << datacenterIdShift) //
| (workerId << workerIdShift) //
| sequence;
}
/**
*
* @param lastTimestamp ID
* @return
*/
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
/**
*
* @return ()
*/
protected long timeGen() {
return System.currentTimeMillis();
}
//==============================Test=============================================
/** 测试 */
public static void main(String[] args) {
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
for (int i = 0; i < 100; i++) {
long id = idWorker.nextId();
//System.out.println(Long.toBinaryString(id));
System.out.println(id);
}
Runnable testRun = new Runnable() {
@Override
public void run() {
SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
for (int i = 0; i < 10; i++) {
System.out.println(idWorker.nextId());
}
}
};
Thread thread1 = new Thread(testRun);
thread1.start();
Thread thread2 = new Thread(testRun);
thread2.start();
Thread thread3 = new Thread(testRun);
thread3.start();
Thread thread4 = new Thread(testRun);
thread4.start();
Thread thread5 = new Thread(testRun);
thread5.start();
}
}

@ -158,11 +158,11 @@ public class ImppEnumUtil {
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum LOG_LEVEL{
DEBUG(1,"DEBUG","调试程序信息"),
INFO(2,"INFO","程序运行信息"),
WARN(3,"WARN","具有潜在危害的信息"),
ERROR(4,"ERROR","错误信息但允许程序继续运行"),
FATAL(5,"FATAL","非常严重的错误,可能导致程序中止");
DEBUG(1,"DEBUG","调试"),
INFO(2,"INFO","信息"),
WARN(3,"WARN","注意"),
ERROR(4,"ERROR","错误"),
FATAL(5,"FATAL","严重");
private int value;
private String name;

@ -16,6 +16,7 @@ import org.bson.json.JsonMode;
import org.bson.json.JsonWriterSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
@ -110,8 +111,26 @@ public class BaseMongoRepositoryImpl<T, ID extends Serializable> extends SimpleM
}
}
this.mongoOperations.insert(item, this.entityInformation.getCollectionName());
if(idField!=null){
// try {
this.mongoOperations.insert(item, this.entityInformation.getCollectionName());
// }catch (DuplicateKeyException dke){
// LOGGER.error("【出现重复主键】");
// //出现重复主键,再次插入
// if(idField != null){
// Class<?> type = idField.getType();
// Object val = idField.get(item);
// if((type == long.class || type == Long.class) && (val == null || Long.parseLong(val.toString()) == 0)){
// // long类型主键以snowflake为主键
// idField.set(item, snowflakeIdMaker.nextId());
// } else if(type == String.class && (val==null || "".equals(val))){
// // String类型主键以UUID为主键
// idField.set(item, UUID.randomUUID().toString().replace("-", "").toLowerCase());
// }
// }
//
// this.mongoOperations.insert(item, this.entityInformation.getCollectionName());
// }
if(idField != null){
return item;
}else {
return null;

@ -37,11 +37,11 @@ public class BaseRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRep
private Class<T> persistentClass;
private SnowflakeIdMaker snowflakeIdMaker;
public BaseRepositoryImpl(Class<T> clz, EntityManager em) {
public BaseRepositoryImpl(Class<T> clz, EntityManager em,SnowflakeIdMaker snowflakeIdMaker) {
super(clz, em);
this.entityManager = em;
this.persistentClass = clz;
this.snowflakeIdMaker = new SnowflakeIdMaker();
this.snowflakeIdMaker = snowflakeIdMaker;
}
private void setParameter(Query query, String[] propName, Object[] propValue) {

@ -1,8 +1,10 @@
package cn.estsh.i3plus.pojo.base.jpa.factory;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.jpa.daoimpl.BaseRepositoryImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
@ -23,6 +25,9 @@ import java.io.Serializable;
public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I extends Serializable> extends JpaRepositoryFactoryBean<R, T, I> {
public static final Logger LOGGER = LoggerFactory.getLogger(BaseRepositoryFactoryBean.class);
@Autowired
public SnowflakeIdMaker snowflakeIdMaker;
public BaseRepositoryFactoryBean(Class<? extends R> repositoryInterface) {
super(repositoryInterface);
}
@ -30,22 +35,24 @@ public class BaseRepositoryFactoryBean<R extends JpaRepository<T, I>, T, I exten
@Override
protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
//LOGGER.info("【初始JPA持久仓】");
return new BaseRepositoryFactory(em);
return new BaseRepositoryFactory(em,snowflakeIdMaker);
}
//创建一个内部类,该类不用在外部访问
private static class BaseRepositoryFactory<T, I extends Serializable> extends JpaRepositoryFactory {
private final EntityManager em;
private final SnowflakeIdMaker snowflakeIdMaker;
public BaseRepositoryFactory(EntityManager em) {
public BaseRepositoryFactory(EntityManager em,SnowflakeIdMaker snowflakeIdMaker) {
super(em);
this.em = em;
this.snowflakeIdMaker = snowflakeIdMaker;
}
//设置具体的实现类是BaseRepositoryImpl
@Override
protected Object getTargetRepository(RepositoryInformation information) {
return new BaseRepositoryImpl<T, I>((Class<T>) information.getDomainType(), em);
return new BaseRepositoryImpl<T, I>((Class<T>) information.getDomainType(), em,snowflakeIdMaker);
}
//设置具体的实现类的class

Loading…
Cancel
Save