web叢集全域性唯一request id生成演算法, 替代uuid等“通用”方案
阿新 • • 發佈:2018-10-31
如何為每一個web請求分配一個在全叢集範圍內都唯一的request id
卻又不想去實現一個複雜的集中式id序列生成器呢?
UUID? 這或許是個辦法,但不覺得不太甘心麼?
下面的這個方式可能可以幫到你:
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這三個要素,並且以合適的轉碼方式組合而成,可以簡單地做到全域性唯一性
生成的唯一性requestId形如:0a11d448iaxk1z35-112 利用它不僅能唯一標識一個請求,還能通過它反查到具體的機器ip