自定义类custom实现IdGenerator接口
新增BpmConfiguration,增加ProcessEnginePlugin bean初始化时指定custom。
import com.fasterxml.uuid.EthernetAddress;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.TimeBasedGenerator;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.camunda.bpm.engine.impl.cfg.IdGenerator;
import org.camunda.bpm.engine.impl.persistence.StrongUuidGenerator;
import org.springframework.stereotype.Component;
/**
* 该类实现的功能是在strongUuidGenerator基础上,去除类'-'
*/
@SuppressWarnings("ALL")
@Component
public class CustomUuidGenerator implements IdGenerator {
protected static volatile TimeBasedGenerator timeBasedGenerator;
private long workerId;
private long datacenterId;
private long sequence = 0L;
// private long twepoch = 1288834974657L; // Thu, 04 Nov 2010 01:42:54 GMT
private long workerIdBits = 5L; // 节点ID长度
private long datacenterIdBits = 5L; // 数据中心ID长度
private long maxWorkerId = -1L ^ (-1L << workerIdBits); // 最大支持机器节点数0~31,一共32个
private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 最大支持数据中心节点数0~31,一共32个
private long sequenceBits = 12L; // 序列号12位
private long workerIdShift = sequenceBits; // 机器节点左移12位
private long datacenterIdShift = sequenceBits + workerIdBits; // 数据中心节点左移17位
// private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; //
// 时间毫秒数左移22位
private long sequenceMask = -1L ^ (-1L << sequenceBits); // 4095
private long lastTimestamp = -1L;
public CustomUuidGenerator() {
ensureGeneratorInitialized(0,0);
}
protected void ensureGeneratorInitialized(long workerId, long datacenterId) {
if (timeBasedGenerator == null) {
synchronized (StrongUuidGenerator.class) {
if (timeBasedGenerator == null) {
timeBasedGenerator = Generators.timeBasedGenerator(EthernetAddress.fromInterface());
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;
}
}
}
}
@Override
public String getNextId() {
//return timeBasedGenerator.generate().toString().replaceAll("-","");
//自定义 nextId 保证 趋势 递增
long timestamp = timeGen(); // 获取当前毫秒数
// 如果服务器时间有问题(时钟后退) 报错。
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只有12bit,所以和sequenceMask相与一下,去掉高位
sequence = (sequence + 1) & sequenceMask;
// 判断是否溢出,也就是每毫秒内超过4095,当为4096时,与sequenceMask相与,sequence就等于0
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp); // 自旋等待到下一毫秒
}
} else {
sequence = 0L; // 如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加
}
lastTimestamp = timestamp;
StringBuilder idStr = new StringBuilder();
String datePrefix = DateFormatUtils.format(timestamp, "yyyyMMddHHmmssSSS");
idStr.append(datePrefix);
Long suffix = (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;
int suffixLen = suffix.toString().length();
if (suffixLen < 4) {
idStr.append(StringUtils.repeat("0", 4 - suffixLen));
}
idStr.append(suffix);
return idStr.toString();
}
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
protected long timeGen() {
return System.currentTimeMillis();
}
public long getWorkerId() {
return workerId;
}
public void setWorkerId(long workerId) {
this.workerId = workerId;
}
public long getDatacenterId() {
return datacenterId;
}
public void setDatacenterId(long datacenterId) {
this.datacenterId = datacenterId;
}
//自测
public static void main(String[] args){
long now = System.currentTimeMillis();
CustomUuidGenerator uuid = new CustomUuidGenerator();
CustomUuidGenerator uuid2 = new CustomUuidGenerator();
uuid2.setWorkerId(1);
uuid2.setDatacenterId(1);
for(int i = 0;i < 1000;i ++){
String nextId = uuid.getNextId();
String next2 = uuid2.getNextId();
System.out.println(i+"nextId1:"+nextId);
System.out.println(i+"nextId2:"+next2);
}
System.out.println("cost:"+(System.currentTimeMillis()- now));
}
}
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.impl.cfg.AbstractProcessEnginePlugin;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
@Slf4j
@Primary
public class BpmConfiguration {
@Autowired
private CustomUuidGenerator customUuidGenerator;
@Bean
public ProcessEnginePlugin statusPlugin() {
return new AbstractProcessEnginePlugin() {
@Override
public void postInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
log.warn("post init");
}
@Override
public void postProcessEngineBuild(ProcessEngine processEngine) {
log.warn("post build");
}
@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
log.warn("pre init");
//BPM 部分实体未实现 序列化接口 通过redis 缓存时无法序列化存储 调整为 通过监听MQ 清理本地缓存
//processEngineConfiguration.setCacheFactory(redisBpm);
// 设置缓存容量 默认为 1000 调整为10000
processEngineConfiguration.setCacheCapacity(10000);
//使用自定义生成的ID
processEngineConfiguration.setIdGenerator(customUuidGenerator);
}
};
}
}