Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinBlandy committed Jun 25, 2021
1 parent fa7b232 commit 5f110eb
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 2 deletions.
115 changes: 115 additions & 0 deletions Codings/IdWorker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
public class IdWorker {
private long workerId;
private long datacenterId;
private long sequence;

/**
*
* @param workerId 机器ID 1-32
* @param datacenterId 数据中心ID 1-32
* @param sequence 毫秒内序列 1-4095
*/
public IdWorker(long workerId, long datacenterId, long sequence) {
// sanity check for workerId
// 这儿不就检查了一下,要求就是你传递进来的机房id和机器id不能超过32,不能小于0
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(
String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
}
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException(
String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
}
System.out.printf(
"worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",
timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);

this.workerId = workerId;
this.datacenterId = datacenterId;
this.sequence = sequence;
}

private long twepoch = 1288834974657L;

private long workerIdBits = 5L;
private long datacenterIdBits = 5L;

// 这个是二进制运算,就是 5 bit最多只能有31个数字,也就是说机器id最多只能是32以内
private long maxWorkerId = -1L ^ (-1L << workerIdBits);

// 这个是一个意思,就是 5 bit最多只能有31个数字,机房id最多只能是32以内
private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
private long sequenceBits = 12L;

private long workerIdShift = sequenceBits;
private long datacenterIdShift = sequenceBits + workerIdBits;
private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
private long sequenceMask = -1L ^ (-1L << sequenceBits);

private long lastTimestamp = -1L;

public long getWorkerId() {
return workerId;
}

public long getDatacenterId() {
return datacenterId;
}

public long getTimestamp() {
return System.currentTimeMillis();
}

public synchronized long nextId() {
// 这儿就是获取当前时间戳,单位是毫秒
long timestamp = timeGen();

if (timestamp < lastTimestamp) {
System.err.printf("clock is moving backwards. Rejecting requests until %d.", lastTimestamp);
throw new RuntimeException(String.format(
"Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
}

if (lastTimestamp == timestamp) {
// 这个意思是说一个毫秒内最多只能有4096个数字
// 无论你传递多少进来,这个位运算保证始终就是在4096这个范围内,避免你自己传递个sequence超过了4096这个范围
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0;
}

// 这儿记录一下最近一次生成id的时间戳,单位是毫秒
lastTimestamp = timestamp;

// 这儿就是将时间戳左移,放到 41 bit那儿;
// 将机房 id左移放到 5 bit那儿;
// 将机器id左移放到5 bit那儿;将序号放最后12 bit;
// 最后拼接起来成一个 64 bit的二进制数字,转换成 10 进制就是个 long 型
return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift)
| (workerId << workerIdShift) | sequence;
}

private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}

private long timeGen() {
return System.currentTimeMillis();
}

// ---------------测试---------------
public static void main(String[] args) {
IdWorker worker = new IdWorker(1, 1, 1);
for (int i = 0; i < 30; i++) {
System.out.println(worker.nextId());
}
}

}
2 changes: 1 addition & 1 deletion Protobuf/protobuf-Maven.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<protoSourceRoot>${project.basedir}/proto</protoSourceRoot>
<!-- 生成类的文件夹 -->
<outputDirectory>${project.build.sourceDirectory}</outputDirectory>
<!-- 是否每次编译前都清空生成文件夹 -->
<!-- 是否每次编译前都清空生成文件夹注意会从 outputDirectory 根目录开始删除 -->
<clearOutputDirectory>false</clearOutputDirectory>
<!-- 临时文件夹 -->
<temporaryProtoFileDirectory>${project.build.directory}/protoc-dependencies</temporaryProtoFileDirectory>
Expand Down
8 changes: 8 additions & 0 deletions Protobuf/protobuf-生成的Java对象.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
* .proto文件中定义的类, 以内部类的形式存在
* 这个文件包含一个单一的outer class定义,包含一些内嵌类和静态字段

* 如果 proto文件的名称和里面定义的message名称一样则生成的java文件为 OuterXxxx
user.proto -> 生成的类 UserOuterClass
|-message User






# 生成的类
* 实现 Message 接口, 并且被标识为 final
Expand Down
23 changes: 22 additions & 1 deletion Protobuf/protobuf.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,21 @@
repeated int32 samples = 4 [packed=true];

* proto3已经默认使用了, 不需要手动声明

* 也是optional字段一样另外加了一个count计数变量用于标明这个字段有多少个这样发送方发送的时候同时发送了count计数变量和这个字段的起始地址接收方在接受到数据之后按照count来解析对应的数据即可

optional
* 可选的
* 就是protobuf处理的时候另外加了一个bool的变量用来标记这个optional字段是否有值发送方在发送的时候如果这个字段有值那么就给bool变量标记为true否则就标记为false
* 接收方在收到这个字段的同时也会收到发送方同时发送的bool变量拿着bool变量就知道这个字段是否有值了这就是option的意思

* 这也就是他们说的所谓平滑升级无非就是个兼容的意思


required
* 必选字段
* proto3不让用了已经




# 字段编号
Expand Down Expand Up @@ -136,6 +150,13 @@
#
* 可以在.proto 文件中选择使用 package 说明符 避免 ProtoBuf 消息类型之间的名称冲突(命名空间)
package foo.bar;
message Open { ... }

message Foo {
...
foo.bar.Open open = 1;
...
}

* Java 里面, 除非在 .proto 文件中显示声明了 option java_package ,否则这个包名会被 Java 直接采用

Expand Down

0 comments on commit 5f110eb

Please sign in to comment.