Poison

GlobalIdGenerator

SkyWalking 中的时钟回拨解决方案:

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public final class GlobalIdGenerator {
private static final String PROCESS_ID = UUID.randomUUID().toString().replaceAll("-", "");
private static final ThreadLocal<IDContext> THREAD_ID_SEQUENCE = ThreadLocal.withInitial(
() -> new IDContext(System.currentTimeMillis(), (short) 0));

private GlobalIdGenerator() {
}

/**
* Generate a new id, combined by three parts.
* <p>
* The first one represents application instance id.
* <p>
* The second one represents thread id.
* <p>
* The third one also has two parts, 1) a timestamp, measured in milliseconds 2) a seq, in current thread, between
* 0(included) and 9999(included)
*
* @return unique id to represent a trace or segment
*/
public static String generate() {
return StringUtil.join(
'.',
PROCESS_ID,
String.valueOf(Thread.currentThread().getId()),
String.valueOf(THREAD_ID_SEQUENCE.get().nextSeq())
);
}

private static class IDContext {
private long lastTimestamp;
private short threadSeq;

// Just for considering time-shift-back only.
private long lastShiftTimestamp;
private int lastShiftValue;

private IDContext(long lastTimestamp, short threadSeq) {
this.lastTimestamp = lastTimestamp;
this.threadSeq = threadSeq;
}

private long nextSeq() {
return timestamp() * 10000 + nextThreadSeq();
}

private long timestamp() {
long currentTimeMillis = System.currentTimeMillis();

if (currentTimeMillis < lastTimestamp) {
// Just for considering time-shift-back by Ops or OS. @hanahmily 's suggestion.
if (lastShiftTimestamp != currentTimeMillis) {
lastShiftValue++;
lastShiftTimestamp = currentTimeMillis;
}
return lastShiftValue;
} else {
lastTimestamp = currentTimeMillis;
return lastTimestamp;
}
}

private short nextThreadSeq() {
if (threadSeq == 10000) {
threadSeq = 0;
}
return threadSeq++;
}
}
}
Reference

GlobalIdGenerator will produce a negative id when the time shift back by nickwongwong · Pull Request #6729 · apache/skywalking
skywalking-java/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/ids/GlobalIdGenerator.java at main · apache/skywalking-java