如何爲每個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