如何为每一个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参见文章:http://segmentfault.com/a/1190000002637818 )
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。