DevilKing's blog

冷灯看剑,剑上几分功名?炉香无需计苍生,纵一穿烟逝,万丈云埋,孤阳还照古陵

0%

ID发生器

原repo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.
├── LICENSE
├── README.md
├── assembly.xml
├── brief.txt
├── deploy-maven.sh
├── make-release.sh
├── pom.xml
├── todo
│   ├── todo.txt
│   └── �\210\206�\203�\217�\217\221�\217��\231�设计�\210�\203��\210\206�\211_�\216\211�\215\216.doc
├── vesta-client
│   ├── pom.xml
│   └── src
├── vesta-doc
│   ├── API�\226\207档.md
│   ├── REST�\217\221�\203模�\217使�\224��\220\221导.md
│   ├── �\213�\215.pptx
│   ├── �\236��\236\204设计.md
│   ├── �\200��\203��\216\213�\213�\212��\221\212.md
│   ├── �\214�\205��\217\221�\203模�\217使�\224��\220\221导.md
│   └── 中�\203�\234\215�\212��\231��\217\221�\203模�\217使�\224��\220\221导.md
├── vesta-intf
│   ├── pom.xml
│   └── src
├── vesta-rest
│   ├── assembly.xml
│   ├── pom.xml
│   └── src
├── vesta-rest-netty
│   ├── assembly.xml
│   ├── pom.xml
│   └── src
├── vesta-sample
│   ├── pom.xml
│   ├── vesta-sample-client
│   └── vesta-sample-embed
├── vesta-server
│   ├── assembly.xml
│   ├── pom.xml
│   └── src
├── vesta-service
│   ├── db
│   ├── pom.xml
│   └── src
└── vesta-theme
└── �\210\221�\232\204微信QR.jpeg

相关的项目结构如上所示。

入口模块为vesta-rest部分,还是vesta-rest-netty部分?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void run() throws Exception {
// Configure the server.
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new VestaRestNettyServerInitializer());

Channel ch = b.bind(new InetSocketAddress("0.0.0.0",port)).sync().channel();

if (log.isDebugEnabled())
log.debug("VestaRestNettyServer is started.");

ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}

使用NioEventLoopGroup

核心的代码都在vesta-service中?

产生ID部分的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public long genId() {
Id id = new Id();

id.setMachine(machineId);
id.setGenMethod(genMethod);
id.setType(idType.value());
id.setVersion(version);

populateId(id);

long ret = idConverter.convert(id, this.idMeta);

// Use trace because it cause low performance
if (log.isTraceEnabled())
log.trace(String.format("Id: %s => %d", id, ret));

return ret;
}

protected void populateId(Id id) {
idPopulator.populateId(timer, id, idMeta);
}

根据类型,分为几种产生ID的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void initPopulator() {
if (idPopulator != null){
log.info("The " + idPopulator.getClass().getCanonicalName() + " is used.");
} else if (CommonUtils.isPropKeyOn(SYNC_LOCK_IMPL_KEY)) {
log.info("The SyncIdPopulator is used.");
idPopulator = new SyncIdPopulator();
} else if (CommonUtils.isPropKeyOn(ATOMIC_IMPL_KEY)) {
log.info("The AtomicIdPopulator is used.");
idPopulator = new AtomicIdPopulator();
} else {
log.info("The default LockIdPopulator is used.");
idPopulator = new LockIdPopulator();
}
}

基本的Id分布为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected long doConvert(Id id, IdMeta idMeta) {
long ret = 0;

ret |= id.getMachine();

ret |= id.getSeq() << idMeta.getSeqBitsStartPos();

ret |= id.getTime() << idMeta.getTimeBitsStartPos();

ret |= id.getGenMethod() << idMeta.getGenMethodBitsStartPos();

ret |= id.getType() << idMeta.getTypeBitsStartPos();

ret |= id.getVersion() << idMeta.getVersionBitsStartPos();

return ret;
}

其他可变部分的产生逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public void populateId(Timer timer, Id id, IdMeta idMeta) {
long timestamp = timer.genTime();
timer.validateTimestamp(lastTimestamp, timestamp);

if (timestamp == lastTimestamp) {
sequence++;
sequence &= idMeta.getSeqBitsMask();
if (sequence == 0) {
timestamp = timer.tillNextTimeUnit(lastTimestamp);
}
} else {
lastTimestamp = timestamp;
sequence = 0;
}

id.setSeq(sequence);
id.setTime(timestamp);
}

采用sequence以及timestamp部分来产生

但atomicId有所不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public void populateId(Timer timer, Id id, IdMeta idMeta) {
Variant varOld, varNew;
long timestamp, sequence;

while (true) {

// Save the old variant
varOld = variant.get();

// populate the current variant
timestamp = timer.genTime();
timer.validateTimestamp(varOld.lastTimestamp, timestamp);

sequence = varOld.sequence;

if (timestamp == varOld.lastTimestamp) {
sequence++;
sequence &= idMeta.getSeqBitsMask();
if (sequence == 0) {
timestamp = timer.tillNextTimeUnit(varOld.lastTimestamp);
}
} else {
sequence = 0;
}

// Assign the current variant by the atomic tools
varNew = new Variant();
varNew.sequence = sequence;
varNew.lastTimestamp = timestamp;

if (variant.compareAndSet(varOld, varNew)) {
id.setSeq(sequence);
id.setTime(timestamp);

break;
}

}
}

通过variant的方式?