在分布式环境下,通常都会有主键id或者单号创建的需求。要求在任何情况下生成的主键id或者单号都是不能够重复的,所以我们需要一种主键或者单号生成机制。这里有一下几种方法:
1、数据库自增
使用mysql数据库的主键id自增
2、redis自增
使用redis的INCR命令实现id自增,INCR命令相关知识参考:http://doc.redisfans.com/string/incr.html
3、使用uuid
uuid的生成规则详见:https://baike.baidu.com/item/UUID/5921266?fr=aladdin
4、雪花算法
雪花算法(SnowFlake),是Twitter开源的分布式id生成算法。其核心思想就是:使用时间戳+工作机器id+序列号生成一个64 bit的long型的数字作为全局唯一id。具体的结构见下图(详细的说明可以百度)
SnowFlake可以保证:
(1)所有生成的id按时间趋势递增
(2)整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)
在java中如何使用雪花算法?这里我们可以不用自己去编写,因为有很多工具都帮我们做好了,我这里使用hutool进行使用的一个演示
在pom中引入hutool的工具包(注:版本需要4.5.9以上)
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.5.9</version>
</dependency>
使用示例代码(主要使用的是IdUtil,顺便吧uuid也编写了)
//生成带-的UUID字符串
System.out.println(IdUtil.randomUUID());
//生成不带-的UUID字符串
System.out.println(IdUtil.simpleUUID());
//使用雪花算法生成id
System.out.println(IdUtil.getSnowflake(0,0).nextId());
//使用雪花算法生成id,返回字符串类型
System.out.println(IdUtil.getSnowflake(1,1).nextIdStr());
System.out.println(IdUtil.getSnowflake(1,1).nextIdStr());
System.out.println(IdUtil.getSnowflake(2,1).nextIdStr());
System.out.println(IdUtil.getSnowflake(2,1).nextIdStr());
结果: