[]Build Status 1 []Quality Gate 1 []Coverage Status 1 []Maven Central 1 []License_ MIT_License_ MIT
id generator with time backward-compatible.
usage
import com.github.gobars.Id;
long bizID = Id.next();
worker_id
Spring 配置:
@Configuration
public class SpringAppConfig {
@Bean
public DataSource getDataSource() {
val dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/id?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=yes&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
@Bean
public IdNext idNext(@Autowired DataSource dataSource) {
val connGetter = new ConnGetter.DsConnGetter(dataSource);
val workerIdDb = new WorkerIdDb().table("worker_id").connGetter(connGetter).biz("default");
val spec = "epoch=20200603,timestampBits=41,backwardBits=0,workerBits=10,seqBits=12,roundMs=1";
return new SnowflakeDb(Conf.fromSpec(spec), workerIdDb);
}
}
Spec说明:
| Spec | 值格式 | 默认值 | 说明 |
| ------------------ | ----------------- | -------- | ---------------------------------------------------------------------------------------- |
| epoch | yyyyMMdd | 20200603 | 服务器第一次上线时间点 |
| timestampBits | 整型 | 41 | 时间戳占用比特位数 |
| roundMs | 整型 | 1 | 时间戳规整到的时间单位(毫秒) |
| backwardBits | 整型 | 0 | 时间回拨序号占用比特位数 |
| workerBits | 整型 | 10 | worker占用比特位数 |
| seqBits | 整型 | 12 | 自增序号占用比特位数 |
| maxBackwardSleepMs | 整型 | 1000 | 最大时间回拨 |
| timestampBy | cache/system/nano | cache | 时间戳计算算法 cache: SystemClock.now(), system: System.currentMillis(),nano: System.nanoTime() |
使用:
@Bean
public class XXService{
@Autowired IdNext id;
public void business() {
// ...
long bizID = id.next();
// ...
}
}
WorkerId 获取顺序
WORKERID
原理
snowflake 改进:
| API | sign | timestamp | backwardId | workerId | sequence | max | limit | years | remark |
|:-----------:|:-----:|:----------:|:----------:|:--------:|:----------:|:--------------------:|:-------:|:----------------------------:|:----------------------------------- |
| - | 符号位 | 时间戳 | 时间回拨序号 | 工作机器ID | 同时间戳内产生的序列 | 最大值 | 限制 | 使用年限 | 备注 |
| Id.next() | 1 bit | 41 bit(ms) | 2 bit | 8 bit | 12 bit | 2^63 | 4096/ms | 2^41/1000/60/60/24/365.5≈69年 | 标准snowflake中10位workerId抽出2位作为时间回拨序号 |
| Id12.next() | 1 bit | 29 bit (s) | 1 bit | 3 bit | 6 bit | 2^39=549,755,813,888 | 64/s | 2^29/60/60/24/365.5 ≈17年 | 产生最大12位长度数字的ID |
时间回拨问题解决方案
最新当前时间上次获取的时间最新当前时间上次获取的时间~/.worker.backwardId.108108
不能解决以下极端条件:
- 程序启动后,停机时间回拨(程序无法感知)
- 程序运行中,连续4次时间回拨(超过最大回拨序号)
资料
脚本
MySQL
drop table if exists worker_id;
create table worker_id
(
id bigint auto_increment primary key comment 'worker id',
created datetime default current_timestamp comment '创建时间',
ip varchar(60) comment '当前机器IP',
hostname varchar(60) comment '当前机器名称',
pid int comment '应用程序PID',
reason varchar(60) comment '申请原因 start:启动 backwards:时间回拨',
biz varchar(60) comment '当前业务名称'
) engine = innodb
default charset = utf8mb4 comment 'worker id 分配表';
or online format:
drop table if exists worker_id;create table worker_id(id bigint auto_increment primary key, created datetime default current_timestamp,ip varchar(60),hostname varchar(60),pid int,reason varchar(60),biz varchar(60))engine = innodb default charset = utf8mb4;
Oracle
drop table worker_id;
create table worker_id
(
id int primary key,
created timestamp default current_timestamp,
ip varchar2(60),
hostname varchar2(60),
pid int,
reason varchar2(60),
biz varchar2(60)
);
comment on table worker_id IS 'worker id 分配表';
comment on column worker_id.id IS 'worker id';
comment on column worker_id.created IS '创建时间';
comment on column worker_id.ip IS '当前机器IP';
comment on column worker_id.hostname IS '当前机器名称';
comment on column worker_id.pid IS '应用程序PID';
comment on column worker_id.reason IS '申请原因 start:启动 backwards:时间回拨';
comment on column worker_id.biz IS '当前业务名称';
CREATE SEQUENCE worker_id_seq
START WITH 1
INCREMENT BY 1
CACHE 100;
CREATE OR REPLACE TRIGGER trigger_worker_id_seq
BEFORE INSERT
ON worker_id
FOR EACH ROW
BEGIN
SELECT worker_id_seq.nextval
INTO :new.id
FROM dual;
END;