如何为每一个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(注:其中引用到的LocalIpAddressUtil参见文章: )