簡介
uid-generator是由百度技術部開發,項目GitHub地址 https://github.com/baidu/uid-generator
UidGenerator是Java實現的, 基於Snowflake算法的唯一ID生成器。
Snowflake算法
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 + Mybatis XML配置的,不適用於SpringBoot,所以自己做了一些改造。
1. 將項目導入本地環境,執行maven install
2. 創建數據表
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;
3. 項目中引入uid-generator依賴,並排除其中的mybatis依賴
由於自己的項目是SpringBoot+Mybatisplus,UidGenerator是Spring+Mybatis,直接引入uid-generator之後,本地項目啓動就會出現創建SqlSessionFactory報錯,所以,我直接將uid-generator中的mybatis相關依賴排除。
<dependency>
<groupId>com.baidu.fsg</groupId>
<artifactId>uid-generator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
4. 利用代碼生成工具,將worker_node對應的代碼生成,並拷貝相關源碼
將源碼中的xml中的方法拷貝到自己的xml文件中:
<resultMap id="workerNodeRes"
type="com.example.mybatisplus.entity.WorkerNode">
<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.example.mybatisplus.entity.WorkerNode">
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方法拷貝到自己的mapper中:
public interface WorkerNodeMapper extends BaseMapper<WorkerNode> {
/**
* Get {@link WorkerNode} by node host
*
* @param host
* @param port
* @return
*/
WorkerNode getWorkerNodeByHostPort(@Param("host") String host, @Param("port") String port);
/**
* Add {@link WorkerNode}
*
* @param workerNodeEntity
*/
void addWorkerNode(WorkerNode workerNodeEntity);
}
5. 自定義DisposableWorkerIdAssigner
將源碼DisposableWorkerIdAssigner類加入到自己的項目中,並將其中的mapper方法修改成自己項目中的方法
6. 添加全局配置類,項目啓動則可以增加機器節點
@Configuration
public class WorkerNodeConfig {
@Bean("disposableWorkerIdAssigner")
public DisposableWorkerIdAssigner disposableWorkerIdAssigner(){
DisposableWorkerIdAssigner disposableWorkerIdAssigner = new DisposableWorkerIdAssigner();
return disposableWorkerIdAssigner;
}
@Bean("cachedUidGenerator")
public UidGenerator uidGenerator(DisposableWorkerIdAssigner disposableWorkerIdAssigner){
CachedUidGenerator cachedUidGenerator = new CachedUidGenerator();
cachedUidGenerator.setWorkerIdAssigner(disposableWorkerIdAssigner);
return cachedUidGenerator;
}
}
6. 在自己service實現中,直接引用UidGenerator方法生成id
@Service
public class WorkerNodeServiceImpl extends ServiceImpl<WorkerNodeMapper, WorkerNode> implements IWorkerNodeService {
@Resource
private UidGenerator uidGenerator;
@Override
public long genUid() {
return uidGenerator.getUID();
}
}
7. controller接口測試結果
/**
* 集成百度uid-generator生成id
* @return
*/
@GetMapping("/baidu/uid")
public long baiduUid(){
long uid = workerNodeService.genUid();
return uid;
}