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 initParam() {// 從默認位置讀取workerId,最大1024try {File conf = new File(WORKERID_PATH);if(conf.exists()){String str = FileUtils.readFileToString(conf);workerId = Integer.parseInt(str);}else{logger.warn(" worker id not found,will use default value...");}} catch(Exception e){e.printStackTrace();}logger.info(" worker id is {}",workerId);if (workerId < 0 || workerId > maxWorkerId) {throw new IllegalArgumentException("workerId is illegal: "+ workerId);}}public long getWorkerId() {return workerId;}public long getTime() {return System.currentTimeMillis();}public String create() {return nextNo();}/*** 獲取id 線程安全** @return*/private synchronized String nextNo() {long timestamp = timeGen();// 時間錯誤if (timestamp < lastTimestamp) {throw new IllegalStateException("Clock moved backwards.");}// 當前毫秒內,則+1if (lastTimestamp == timestamp) {// 當前毫秒內計數滿了,則等待下一秒sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0;}lastTimestamp = timestamp;// ID偏移組合生成最終的ID,并返回ID,最大十位數long id = ((timestamp % 1000) << timestampLeftShift) | (workerId << workerIdShift) | sequence;String timestampStr = DateFormatUtils.NUMBER_FORMAT.format(timestamp);return timestampStr+String.format("%010d",id);}/*** 等待下一個毫秒的到來** @param lastTimestamp* @return*/private long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}/*** 最大十位,最小7位,補0format*//*public void test(){String t = String.valueOf((1L << 22) | (1 << 12) | 0);String t1 = String.valueOf((999L << 22) | (1023 << 12) | 0);System.out.println(DateFormatUtils.NUMBER_FORMAT.format(System.currentTimeMillis())+"-"+t);System.out.println(DateFormatUtils.NUMBER_FORMAT.format(System.currentTimeMillis())+"-"+t1);long l1 = (1L << 22) | (1 << 12) | 0;long l2 = (999L << 22) | (1023 << 12) | 0;System.out.println(l1);System.out.println(l2);System.out.println(String.format("%010d",l1));System.out.println(String.format("%010d",l2));}*/public static void main(String[] args){for (int i = 0; i < 100; i++) {System.out.println(OrderNoCenter.getInstance().create());}//性能測試TimeMark mark = new TimeMark();for (int i = 0; i < 1000000; i++) {OrderNoCenter.getInstance().create();}mark.simplePrint();mark.mark();for (int i = 0; i < 1000000; i++) {IdCenter.getInstance().getId();}mark.simplePrint();}
}
缺少代碼的話,請直接使用我的附件代碼
附件:
代碼代碼代碼代碼代碼點擊下載下載
轉載于:https://www.cnblogs.com/luochengqiuse/p/6747895.html
總結
以上是生活随笔為你收集整理的业务订单号生成算法,每秒50W左右,不同机器保证不重复,包含日期可读性好...的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。