产生背景
随着业务体量的增大,以及对系统高可用的要求,集群部署是现在非常常见的部署方式,这个时候需要保证记录日志的编号是唯一的.
核心代码
public static final int nextValue(){ ATOMIC_INTEGER.compareAndSet(1000000, 100000); return ATOMIC_INTEGER.getAndIncrement(); } public static final String get() { return String.valueOf(System.currentTimeMillis()) + App.ID + nextValue(); }
代码分析
ATOMIC_INTEGER 是线程安全的类,调用getAndIncrement 方法来实现线程安全的自增长,其底层用的是 CAS自旋锁来保证线程安全. 但是只有这一句代码是不够的,如果服务器不重启的话,那么他会一直自增下去,导致超出范围使程序报错,所以我们需要调用 compareAndSet 方法 设置一个自增的最大值,如果超过该最大值,则从指定的数值开始.
如果是单台机器的话,已经没有问题了,但是如果是多台机器,还是有可能会出现相同的编号的,我们可以给每台机器去单独制定一个id,这样就能保证编号是唯一的了.
最终生成日志的算法变为 时间戳 + appid + 自增值,这样就可以保证唯一了.