springboot集成uid-generator生成分布式id

作者 : admin 本文共5481个字,预计阅读时间需要14分钟 发布时间: 2024-06-10 共3人阅读

一、简介

uid-generator是由百度技术部开发,GitHub地址

UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器

Snowflake算法

springboot集成uid-generator生成分布式id插图
Snowflake算法描述:指定机器 & 同一时刻 & 某一并发序列,是唯一的。据此可生成一个64 bits的唯一ID(long)。默认采用上图字节分配方式:

sign(1bit)固定1bit符号标识,即生成的UID为正数。
delta seconds (28 bits)当前时间,相对于时间基点”2016-05-20″的增量值,单位:秒,最多可支持约8.7年
worker id (22 bits)机器id,最多可支持约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
sequence (13 bits)每秒下的并发序列,13 bits可支持每秒8192个并发。

二、使用Spring boot项目集成uid-generator

2.1 将项目下载之后生成文件

springboot集成uid-generator生成分布式id插图(1)

下载完成后使用IDEA打开

springboot集成uid-generator生成分布式id插图(2)

复制生成的文件夹到maven仓库

springboot集成uid-generator生成分布式id插图(3)

我的maven仓库安装到了d盘

springboot集成uid-generator生成分布式id插图(4)

之后就可以使用标签引入了

2.2项目中引入uid-generator依赖,并排除其中的mybatis依赖

如果项目是SpringBoot+Mybatisplus,UidGenerator是Spring+Mybatis,直接引入uid-generator之后,本地项目启动就会出现创建SqlSessionFactory报错,所以,直接将uid-generator中的mybatis相关依赖排除。避免出现不必要的启动问题


    com.baidu.fsg
    uid-generator
    1.0.0-SNAPSHOT
    
        
            org.mybatis
            *
        
    


2.3 创建数据库表

DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
 COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;

2.4 生成实体类与mapper

2.4.1实体类
import java.util.Date;

public class WorkerNode {

    private Long id;

    private String hostName;

    private String port;

    private Integer type;

    private Date LaunchDate;

    private Date modified;

    private Date created;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    public Date getLaunchDate() {
        return LaunchDate;
    }

    public void setLaunchDate(Date launchDate) {
        LaunchDate = launchDate;
    }

    public Date getModified() {
        return modified;
    }

    public void setModified(Date modified) {
        this.modified = modified;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    @Override
    public String toString() {
        return "WorkerNode{" +
                "id=" + id +
                ", hostName='" + hostName + '\'' +
                ", port='" + port + '\'' +
                ", type=" + type +
                ", LaunchDate=" + LaunchDate +
                ", modified=" + modified +
                ", created=" + created +
                '}';
    }
}

2.4.2 mapper与mapper.xml
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface WorkerNodeMapper {

    int addWorkerNode(WorkerNode workerNodeEntity);


    WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);

}



    
        
        
        
        
        
        
        
    

    
        INSERT INTO WORKER_NODE
        (HOST_NAME,
         PORT,
         TYPE,
         LAUNCH_DATE,
         MODIFIED,
         CREATED)
        VALUES (
                   #{hostName},
                   #{port},
                   #{type},
                   #{launchDate},
                   NOW(),
                   NOW())
    

    
        SELECT
            ID,
            HOST_NAME,
            PORT,
            TYPE,
            LAUNCH_DATE,
            MODIFIED,
            CREATED
        FROM
            WORKER_NODE
        WHERE
            HOST_NAME = #{host} AND PORT = #{port}
    


注:
springboot集成uid-generator生成分布式id插图(5)

修改对应位置为自己实体类与mapper所在位置

2.5 service与impl

  • service
/**
 * @注释
 */
public interface IWorkerNodeService {

    public long genUid();
}
  • serviceimpl
import com.baidu.fsg.uid.UidGenerator;
import com.lq.service.IWorkerNodeService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 */
@Service
public class WorkerNodeServiceImpl implements IWorkerNodeService {
    @Resource
    private UidGenerator uidGenerator;

    @Override
    public long genUid() {
        return uidGenerator.getUID();
    }
}

2.6 添加配置类

springboot集成uid-generator生成分布式id插图(6)

2.6.1 DisposableWorkerIdAssigner
import com.baidu.fsg.uid.utils.DockerUtils;
import com.baidu.fsg.uid.utils.NetUtils;
import com.baidu.fsg.uid.worker.WorkerIdAssigner;
import com.baidu.fsg.uid.worker.WorkerNodeType;
import org.apache.commons.lang.math.RandomUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

/**
 */
public class DisposableWorkerIdAssigner implements WorkerIdAssigner {

    @Resource
    private WorkerNodeMapper workerNodeMapper;

    @Override
    @Transactional
    public long assignWorkerId() {
        WorkerNode workerNode = buildWorkerNode();

        workerNodeMapper.addWorkerNode(workerNode);

        return workerNode.getId();
    }

    private WorkerNode buildWorkerNode() {
        WorkerNode workNode = new WorkerNode();
        if (DockerUtils.isDocker()) {
            workNode.setType(WorkerNodeType.CONTAINER.value());
            workNode.setHostName(DockerUtils.getDockerHost());
            workNode.setPort(DockerUtils.getDockerPort());
            workNode.setLaunchDate(new Date());
        } else {
            workNode.setType(WorkerNodeType.ACTUAL.value());
            workNode.setHostName(NetUtils.getLocalAddress());
            workNode.setPort(System.currentTimeMillis() + "-" + RandomUtils.nextInt(100000));
            workNode.setLaunchDate(new Date());
        }

        return workNode;
    }
}
2.6.2 WorkerNodeConfig
import com.baidu.fsg.uid.UidGenerator;
import com.baidu.fsg.uid.impl.CachedUidGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** 
 */
@Configuration
public class WorkerNodeConfig {

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

    @Bean("cachedUidGenerator")
    public UidGenerator uidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner){
        CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
        cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
        return cachedUidGenerator;
    }
}

2.7 测试

import com.lq.service.IWorkerNodeService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 */
@SpringBootTest
public class UidGenerateTest {

    @Resource
    private IWorkerNodeService workerNodeService;

    @Test
    public void getUid() {
        List list = new ArrayList();
        for (int i = 0; i  {
            System.out.println("第" + num.getAndIncrement() + "个id为 = " + l);
        });
    }
}

springboot集成uid-generator生成分布式id插图(7)

本站无任何商业行为
个人在线分享 » springboot集成uid-generator生成分布式id
E-->