业务订单号生成算法
- 参考snowflake算法,基本思路:
- 序列12位(更格式化的输出后,性能损耗导致每毫秒生成不了这么多,所以可以考虑减少这里的位,不过留着也并无影响)
- 机器位10位
-
毫秒为左移 22位
-
上述几个做或运算后得出一个唯一的数,转10进制后,最大10位,最小7位,string.format来统一为10,format性能影响,导致性能降低3倍左右
FilUtils不想用的话,1太机器可以直接考虑使用1,多机器根据代码配置id
代码如下:
package net.gitosc.lianqu1990.utils.code;
import net.gitosc.lianqu1990.utils.date.DateFormatUtils;
import net.gitosc.lianqu1990.utils.date.TimeMark;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
/**
* 缺陷是,订单量没那么大,导致机器码|序列 后,一般都是4096
* 通过将毫秒引入序列后修正
* 后来加了format以后性能受损,比idcenter慢10倍,每秒可以生成50w,idcenter将近500w,不过这也是idcenter极限
* 够用,暂不优化
* @author hanchao
* @date 2017/4/20 19:01
*/
public class OrderNoCenter {
public static final Logger logger = LoggerFactory.getLogger(OrderNoCenter.class);
private static final String WORKERID_PATH = "/etc/workerId";
private OrderNoCenter() {
}
private static class OrderNoCenterHolder{
private static OrderNoCenter instance = new OrderNoCenter();
}
public static OrderNoCenter getInstance() {
return OrderNoCenterHolder.instance;
}
/**
* 节点 ID 默认取1
*/
private long workerId = 1;
/**
* 序列id 默认取1
*/
private long sequence = 1;
/**
* 机器标识位数
*/
private final long workerIdBits = 10L;
/**
* 机器ID最大值
*/
private final long maxWorkerId = -1L ^ (-1L << workerIdBits); //结果就是2的workerBits次方-1,能表示的最大数.全部1亦或10位0,就是0开头最后10位1
/**
* 毫秒内自增位
*/
private final long sequenceBits = 12L;
/**
* 机器ID偏左移12位
*/
private final long workerIdShift = sequenceBits;
/**
* 数据中心ID左移17位
*/
private final long datacenterIdShift = sequenceBits + workerIdBits;
private final long sequenceMask = -1L ^ (-1L << sequenceBits);
/**
* 时间毫秒左移22位
*/
private final long timestampLeftShift = sequenceBits + workerIdBits;
private long lastTimestamp = -1L;
public void