1. 程式人生 > >web叢集全域性唯一request id生成演算法, 替代uuid等“通用”方案

web叢集全域性唯一request id生成演算法, 替代uuid等“通用”方案

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