Java生成全局唯一ID代码演示

看了GitHub上的两个生成唯一ID的算法程序(一个出自百度,一个出自美团),打算运行着试试看,至于原理什么的文档上讲得很详细了,此处不再一一粘贴了,此处只演示代码

https://github.com/baidu/uid-generator

https://github.com/zhuzhong/idleaf

百度UID生成器

1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4     <modelVersion>4.0.0</modelVersion>
 5
 6     <groupId>com.cjs.example</groupId>
 7     <artifactId>uid-generator-demo</artifactId>
 8     <version>0.0.1-SNAPSHOT</version>
 9     <packaging>jar</packaging>
10
11     <name>uid-generator-demo</name>
12     <description></description>
13
14     <parent>
15         <groupId>org.springframework.boot</groupId>
16         <artifactId>spring-boot-starter-parent</artifactId>
17         <version>2.0.3.RELEASE</version>
18         <relativePath/> <!-- lookup parent from repository -->
19     </parent>
20
21     <properties>
22         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
24         <java.version>1.8</java.version>
25     </properties>
26
27     <dependencies>
28         <dependency>
29             <groupId>org.mybatis.spring.boot</groupId>
30             <artifactId>mybatis-spring-boot-starter</artifactId>
31             <version>1.3.2</version>
32         </dependency>
33         <dependency>
34             <groupId>mysql</groupId>
35             <artifactId>mysql-connector-java</artifactId>
36             <version>5.1.46</version>
37         </dependency>
38
39         <dependency>
40             <groupId>org.apache.commons</groupId>
41             <artifactId>commons-collections4</artifactId>
42             <version>4.2</version>
43         </dependency>
44         <dependency>
45             <groupId>org.apache.commons</groupId>
46             <artifactId>commons-lang3</artifactId>
47             <version>3.7</version>
48         </dependency>
49
50         <dependency>
51             <groupId>org.springframework.boot</groupId>
52             <artifactId>spring-boot-starter-test</artifactId>
53             <scope>test</scope>
54         </dependency>
55     </dependencies>
56
57     <build>
58         <plugins>
59             <plugin>
60                 <groupId>org.springframework.boot</groupId>
61                 <artifactId>spring-boot-maven-plugin</artifactId>
62             </plugin>
63         </plugins>
64     </build>
65
66 </project>

  

SQL脚本

1 DROP DATABASE IF EXISTS `mytest`;
 2 CREATE DATABASE `mytest` ;
 3 use `mytest`;
 4 DROP TABLE IF EXISTS WORKER_NODE;
 5 CREATE TABLE WORKER_NODE
 6 (
 7     ID BIGINT NOT NULL AUTO_INCREMENT COMMENT ‘auto increment id‘,
 8     HOST_NAME VARCHAR(64) NOT NULL COMMENT ‘host name‘,
 9     PORT VARCHAR(64) NOT NULL COMMENT ‘port‘,
10     TYPE INT NOT NULL COMMENT ‘node type: ACTUAL or CONTAINER‘,
11     LAUNCH_DATE DATE NOT NULL COMMENT ‘launch date‘,
12     MODIFIED TIMESTAMP NOT NULL COMMENT ‘modified time‘,
13     CREATED TIMESTAMP NOT NULL COMMENT ‘created time‘,
14     PRIMARY KEY(ID)
15 )COMMENT=‘DB WorkerID Assigner for UID Generator‘,ENGINE = INNODB;
复制代码

mapper文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cjs.example.baidu.uid.worker.dao.WorkerNodeDAO">
    <resultMap id="workerNodeRes"
               type="com.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity">
        <id column="ID" jdbcType="BIGINT" property="id" />
        <result column="HOST_NAME" jdbcType="VARCHAR" property="hostName" />
        <result column="PORT" jdbcType="VARCHAR" property="port" />
        <result column="TYPE" jdbcType="INTEGER" property="type" />
        <result column="LAUNCH_DATE" jdbcType="DATE" property="launchDate" />
        <result column="MODIFIED" jdbcType="TIMESTAMP" property="modified" />
        <result column="CREATED" jdbcType="TIMESTAMP" property="created" />
    </resultMap>

    <insert id="addWorkerNode" useGeneratedKeys="true" keyProperty="id"
        parameterType="com.cjs.example.baidu.uid.worker.entity.WorkerNodeEntity">
        INSERT INTO WORKER_NODE
        (HOST_NAME,
        PORT,
        TYPE,
        LAUNCH_DATE,
        MODIFIED,
        CREATED)
        VALUES (
        #{hostName},
        #{port},
        #{type},
        #{launchDate},
        NOW(),
        NOW())
    </insert>

    <select id="getWorkerNodeByHostPort" resultMap="workerNodeRes">
        SELECT
        ID,
        HOST_NAME,
        PORT,
        TYPE,
        LAUNCH_DATE,
        MODIFIED,
        CREATED
        FROM
        WORKER_NODE
        WHERE
        HOST_NAME = #{host} AND PORT = #{port}
    </select>
</mapper>

application.yml配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mytest
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml

Spring Bean配置

package com.cjs.example;

import com.cjs.example.baidu.uid.impl.CachedUidGenerator;
import com.cjs.example.baidu.uid.impl.DefaultUidGenerator;
import com.cjs.example.baidu.uid.worker.DisposableWorkerIdAssigner;
import com.cjs.example.baidu.uid.worker.WorkerIdAssigner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@SpringBootApplication
public class UidGeneratorDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(UidGeneratorDemoApplication.class, args);
    }

    @Autowired
    private WorkerIdAssigner workerIdAssigner;

    @Bean
    public DefaultUidGenerator defaultUidGenerator() {
        DefaultUidGenerator defaultUidGenerator = new DefaultUidGenerator();
        defaultUidGenerator.setWorkerIdAssigner(workerIdAssigner);
        defaultUidGenerator.setTimeBits(29);
        defaultUidGenerator.setWorkerBits(21);
        defaultUidGenerator.setSeqBits(13);
        defaultUidGenerator.setEpochStr("2018-07-21");
        return defaultUidGenerator;
    }

    @Bean
    public DisposableWorkerIdAssigner disposableWorkerIdAssigner() {
        return new DisposableWorkerIdAssigner();
    }

    @Bean
    public CachedUidGenerator cachedUidGenerator() {
        CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
        cachedUidGenerator.setWorkerIdAssigner(workerIdAssigner);
        cachedUidGenerator.setTimeBits(29);
        cachedUidGenerator.setWorkerBits(21);
        cachedUidGenerator.setSeqBits(13);
        cachedUidGenerator.setEpochStr("2018-07-21");
        return cachedUidGenerator;
    }

}

测试

package com.cjs.example;

import com.cjs.example.baidu.uid.impl.CachedUidGenerator;
import com.cjs.example.baidu.uid.impl.DefaultUidGenerator;
import com.cjs.example.meituan.idleaf.IdLeafService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UidGeneratorDemoApplicationTests {

    @Autowired
    @Qualifier("defaultUidGenerator")
    private DefaultUidGenerator defaultUidGenerator;

    @Autowired
    @Qualifier("cachedUidGenerator")
    private CachedUidGenerator cachedUidGenerator;

26     27
    @Test
    public void testSerialGenerate() {
        long uid = defaultUidGenerator.getUID();
        System.out.println(uid);
        System.out.println(defaultUidGenerator.parseUID(uid));
    }

    @Test
    public void testSerialGenerate2() {
        long uid = cachedUidGenerator.getUID();
        System.out.println(uid);
        System.out.println(cachedUidGenerator.parseUID(uid));
    }

}

美团UID生成器

Maven依赖

1 <dependency>
2     <groupId>org.apache.ignite</groupId>
3     <artifactId>ignite-zookeeper</artifactId>
4     <version>2.4.0</version>
5 </dependency>

SQL脚本

DROP TABLE IF EXISTS `id_segment`;

CREATE TABLE `id_segment` (
  `biz_tag` varchar(50) DEFAULT NULL COMMENT ‘业务标识‘,
  `max_id` bigint(20) DEFAULT NULL COMMENT ‘分配的id号段的最大值‘,
  `p_step` bigint(20) DEFAULT NULL COMMENT ‘步长‘,
  `last_update_time` datetime DEFAULT NULL,
  `current_update_time` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=‘号段存储表‘;

insert  into `id_segment`(`biz_tag`,`max_id`,`p_step`,`last_update_time`,`current_update_time`) values (‘Order‘,60,20,‘2018-07-21 15:44:02‘,‘2018-07-21 16:25:07‘);

Spring Bean配置

package com.cjs.example;

import com.cjs.example.meituan.idleaf.IdLeafService;
import com.cjs.example.meituan.idleaf.support.MysqlIdLeafServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@SpringBootApplication
public class UidGeneratorDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(UidGeneratorDemoApplication.class, args);
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Bean(initMethod = "init")
    public IdLeafService idLeafService() {
        MysqlIdLeafServiceImpl mysqlIdLeafService = new MysqlIdLeafServiceImpl();
        mysqlIdLeafService.setJdbcTemplate(jdbcTemplate);
        mysqlIdLeafService.setAsynLoadingSegment(true);
        mysqlIdLeafService.setBizTag("Order");
        return mysqlIdLeafService;
    }
}

测试

@Autowired
private IdLeafService idLeafService;

@Test
public void testSerialGenerate3() {
    Long id = idLeafService.getId();
    System.out.println(id);
}

个人感觉无论是从文档,原理,还是代码,觉得还是百度的那个比较好用(哇咔咔O(∩_∩)O哈哈~)

还有一个Redis的方案感觉也不错

完整代码上传至  https://github.com/chengjiansheng/uid-generator-demo.git

参考

https://github.com/baidu/uid-generator

https://tech.meituan.com/MT_Leaf.html?utm_source=tuicool&utm_medium=referral

https://github.com/zhuzhong/idleaf

https://blog.csdn.net/liubenlong007/article/details/53884447

https://www.cnblogs.com/baiwa/p/5318432.html

https://blog.csdn.net/imi00/article/details/78629710

最后,关于RingBuffer(循环缓冲区,或者叫 环形缓冲区)

https://blog.csdn.net/u011046042/article/details/51853535

https://www.jianshu.com/p/c3913c5cc184

https://blog.csdn.net/z69183787/article/details/52403134

原文地址:https://www.cnblogs.com/a8457013/p/10075718.html

时间: 2024-11-07 10:47:23

Java生成全局唯一ID代码演示的相关文章

高并发分布式系统中生成全局唯一Id汇总

高并发分布式系统中生成全局唯一Id汇总 (转自:http://www.cnblogs.com/baiwa/p/5318432.html) 数据在分片时,典型的是分库分表,就有一个全局ID生成的问题.单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求:   1 不能有单点故障.   2 以时间为序,或者ID里包含时间.这样一是可以少一个索引,二是冷热数据容易分离.   3 可以控制ShardingId.比如某一个用户的文章要放在同一个分片内,这样查询效率高,修改也容易.   

如何在高并发分布式系统中生成全局唯一Id(转)

http://www.cnblogs.com/heyuquan/p/global-guid-identity-maxId.html 又一个多月没冒泡了,其实最近学了些东西,但是没有安排时间整理成博文,后续再奉上.最近还写了一个发邮件的组件以及性能测试请看 <NET开发邮件发送功能的全面教程(含邮件组件源码)> ,还弄了个MSSQL参数化语法生成器,会在9月整理出来,有兴趣的园友可以关注下我的博客. 分享原由,最近公司用到,并且在找最合适的方案,希望大家多参与讨论和提出新方案.我和我的小伙伴们也

游戏服务器生成全局唯一ID的几种方法

在服务器系统开发时,为了适应数据大并发的请求,我们往往需要对数据进行异步存储,特别是在做分布式系统时,这个时候就不能等待插入数据库返回了取自动id了,而是需要在插入数据库之前生成一个全局的唯一id,使用全局的唯一id,在游戏服务器中,全局唯一的id可以用于将来合服方便,不会出现键冲突.也可以将来在业务增长的情况下,实现分库分表,比如某一个用户的物品要放在同一个分片内,而这个分片段可能是根据用户id的范围值来确定的,比如用户id大于1000小于100000的用户在一个分片内.目前常用的有以下几种:

通过Zookeeper学习在分布式系统中生成全局唯一ID

Session是Zookeeper中的会话实体,代表了一个客户端会话.SessionID用来唯一标识一个会话,因此Zookeeper必须保证sessionID的全局唯一性,在每次客户端向服务端发起"会话创建"请求时,服务端都会为其分配一个sessionID.那么Zookeeper是如何实现的呢? 在SessionTracker初始化的时候,会调用initializeNextSession方法来生成一个初始化的sessionID,之后在Zookeeper的正常运行过程中,会在该sessi

如何在高并发分布式系统中生成全局唯一Id

我了解的方案如下-------------------------- 1.  使用数据库自增Id 优势:编码简单,无需考虑记录唯一标识的问题. 缺陷: 1)         在大表做水平分表时,就不能使用自增Id,因为Insert的记录插入到哪个分表依分表规则判定决定,若是自增Id,各个分表中Id就会重复,在做查询.删除时就会有异常. 2)         在对表进行高并发单记录插入时需要加入事物机制,否则会出现Id重复的问题. 3)         在业务上操作父.子表(即关联表)插入时,需要

SnowFlake 生成全局唯一id

public class SnowFlakeUtil { private long workerId; private long datacenterId; private long sequence = 0L; private long twepoch = 1288834974657L; // Thu, 04 Nov 2010 01:42:54 GMT 标记时间 用来计算偏移量,距离当前时间不同,得到的数据的位数也不同 private long workerIdBits = 5L; // 物理

python 中md5 和 sha1 加密, md5 + os.urandom 生成全局唯一ID

首先先来介绍一下md5 和 sha1 的概念 MD5 MD5的全称是Message-Digest Algorithm 5(信息-摘要算法).128位长度.目前MD5是一种不可逆算法. 具有很高的安全性.它对应任何字符串都可以加密成一段唯一的固定长度的代码. SHA1 SHA1的全称是Secure Hash Algorithm(安全哈希算法) .SHA1基于MD5,加密后的数据长度更长, 它对长度小于264的输入,产生长度为160bit的散列值.比MD5多32位. 因此,比MD5更加安全,但SHA

Java中SnowFlake 雪花算法生成全局唯一id中的问题,时间不连续全为偶数解决

package com.example.springbootshardingjdbc.util; import java.io.FileOutputStream; /** * 描述: Twitter的分布式自增ID雪花算法snowflake (Java版) * * @author * @create 2018-03-13 12:37 **/ public class SnowFlake { /** * 起始的时间戳 */ private final static long START_STMP

生成全局唯一id

http://littcai.iteye.com/blog/1900018 http://www.oschina.net/question/575914_90957 http://www.dengchuanhua.com/132.html twitter/snowflake https://github.com/twitter/snowflake https://twitter.github.io/twitter-server/