1. 程式人生 > >雪花演算法(snowflake) :分散式環境,生成全域性唯一的訂單號

雪花演算法(snowflake) :分散式環境,生成全域性唯一的訂單號

準備

apache.commons.lang3包
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>
​​​
讀取配置檔案:https://blog.csdn.net/fly910905/article/details/78737323

工具類

package com.datalook.util.common;

import org.apache.commons.lang3.time.DateFormatUtils;


import java.util.Date;
/**
 * 
 * @Title:  訂單號生成
 * @ClassName:OrderIdUtils.java
 * @Description:
 *
 * @Copyright 2016-2017  - Powered By 研發中心
 * @author: 王延飛
 * @date:2018年3月22日 下午7:43:30
 * @version V1.0
 */
public class OrderIdUtils {

    // 最近的時間戳
    private long lastTimestamp=0;
    //機器id 2位
    private final String machineId;
    // 0,併發控制
    private long sequence = 0L;
    // 序列號的最大值
    private final int sequenceMax = 9999;


    public OrderIdUtils(String machineId) {
        this.machineId = machineId;
    }

    /**
     * 生成訂單號
     */
    public synchronized String nextId(){
        Date now=new Date();
        String time= DateFormatUtils.format(now,"yyMMddHHmmssSSS");
        long timestamp = now.getTime();
        if (this.lastTimestamp == timestamp) {
            // 如果上一個timestamp與新產生的相等,則sequence加一(0-4095迴圈);
            // 對新的timestamp,sequence從0開始
            this.sequence = this.sequence + 1 % this.sequenceMax;
            if (this.sequence == 0) {
                // 重新生成timestamp
                timestamp = this.tilNextMillis(this.lastTimestamp);
            }
        } else {
            this.sequence = 0;
        }
        this.lastTimestamp= timestamp;
        StringBuilder sb=new StringBuilder(time).append(machineId).append(leftPad(sequence,4));
        return sb.toString();
    }

    /**
     * 補碼
     * @param i
     * @param n
     * @return
     */
    private String leftPad(long i,int n){
        String s = String.valueOf(i);
        StringBuilder sb=new StringBuilder();
        int c=n-s.length();
        c=c<0?0:c;
        for (int t=0;t<c;t++){
            sb.append("0");
        }
        return sb.append(s).toString();
    }

    /**
     * 等待下一個毫秒的到來, 保證返回的毫秒數在引數lastTimestamp之後
     */
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }

    // 這裡讀取的是配置檔案
    // 機器id(我這裡是01,正式環境建議使用機器IP)
    // 注意:分散式環境,注意每臺機器的id要保證不同;也可以使用機器ip,對映成一個數字編號(如01:192.168.55.12)
    private static String myid= SysConstant.LOCAL_MACHINE_ID;

    // 示例
    private static OrderIdUtils instance = new OrderIdUtils(myid);
    public static OrderIdUtils getInstance() {
        return instance;
    }
    
    
    
    /**
     * 
     * @Title: 獲取訂單號
     * @return String
     * @Description:
     *
     * @author: 王延飛
     * @date: 2018年3月22日 下午7:56:56
     */
    public static  String getOrderNumber() {

        OrderIdUtils orderId = OrderIdUtils.getInstance();
        String nextId = orderId.nextId();

        return nextId;
    }

    /**
     * 呼叫
     */
    public static void main(String[] args) {
        OrderIdUtils orderId= OrderIdUtils.getInstance();
        String nextId = orderId.nextId();
        int length = nextId.length();
        System.out.println(nextId);
        System.out.println(length);

    }
}