分享代码片断:web集群全局惟一request id生成算法, 替代uuid等“通用”方案

如何为每个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

相关文章
相关标签/搜索