分享代碼片斷:web集羣全局惟一request id生成算法, 替代uuid等「通用」方案

如何爲每個web請求分配一個在全集羣範圍內都惟一的request id,卻又不想去實現一個複雜的集中式id序列生成器呢?
UUID? 這或許是個辦法,但不以爲不太甘心麼?
下面的這個方式可能能夠幫到你:java

package test;

import java.util.concurrent.atomic.AtomicLong;

import test.LocalIpAddressUtil;

public class UniqRequestIdGen {

    private static AtomicLong   lastId         = new AtomicLong();                                         // 自增id,用於requestId的生成過程
    private static final long   startTimeStamp = System.currentTimeMillis();                               // 啓動加載時的時間戳,用於requestId的生成過程
    private static final String ip             = LocalIpAddressUtil.resolveLocalAddress().getHostAddress(); // 本機ip地址,用於requestId的生成過程

    public static void main(String[] args) {
        System.out.println(resolveReqId());
    }

    private static String resolveReqId() {
        // 規則: hexIp(ip)base36(timestamp)-seq
        return hexIp(ip) + Long.toString(startTimeStamp, Character.MAX_RADIX) + "-" + lastId.incrementAndGet();
    }

    // 將ip轉換爲定長8個字符的16進製表示形式:255.255.255.255 -> FFFFFFFF
    private static String hexIp(String ip) {
        StringBuilder sb = new StringBuilder();
        for (String seg : ip.split("\\.")) {
            String h = Integer.toHexString(Integer.parseInt(seg));
            if (h.length() == 1) sb.append("0");
            sb.append(h);
        }
        return sb.toString();
    }

}

其思路在註釋裏已經解釋清楚了:這個id包含了本機ip、本應用啓動時的時間戳、本應用內部自增id這三個要素,而且以合適的轉碼方式組合而成,能夠簡單地作到全局惟一性web

生成的惟一性requestId形如:0a11d448iaxk1z35-112
利用它不只能惟一標識一個請求,還能經過它反查到具體的機器ipsegmentfault

(注:其中引用到的LocalIpAddressUtil參見文章:http://segmentfault.com/a/1190000002637818 )app

相關文章
相關標籤/搜索