From 2b566caee56b6f09a9e188a9d476ef2c454b40a0 Mon Sep 17 00:00:00 2001 From: wangkang Date: Mon, 4 Sep 2017 19:57:23 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0snowflake=E7=9A=84datacenterI?= =?UTF-8?q?d=E5=92=8CworkerId=E7=9A=84ID=E5=88=86=E9=85=8D=E7=AD=96?= =?UTF-8?q?=E7=95=A5,=E5=88=A9=E7=94=A8redis=E7=9A=84=E5=8E=9F=E5=AD=90?= =?UTF-8?q?=E9=94=81=E7=89=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/itkk/udf/id/IdWorkerConfig.java | 16 --------- .../java/org/itkk/udf/id/IdWorkerInit.java | 36 +++++++++++++++---- .../itkk/udf/id/web/IdWorkerController.java | 10 +++--- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerConfig.java b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerConfig.java index 7ad35e1..fd866f6 100644 --- a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerConfig.java +++ b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerConfig.java @@ -1,6 +1,5 @@ package org.itkk.udf.id; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** @@ -9,19 +8,4 @@ import org.springframework.context.annotation.Configuration; @Configuration public class IdWorkerConfig { - - /** - * 分布式ID生成器 - * - * @param idWorkerInit idWorkInit - * @return idWorkInit - */ - @Bean - public IdWorker idWorker(IdWorkerInit idWorkerInit) { - //初始化 - idWorkerInit.init(); - //返回 - return idWorkerInit.get(); - } - } diff --git a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerInit.java b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerInit.java index 07d5f4a..f7c27a2 100644 --- a/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerInit.java +++ b/udf-starter-id/src/main/java/org/itkk/udf/id/IdWorkerInit.java @@ -10,7 +10,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -import java.util.Date; +import javax.annotation.PostConstruct; +import java.util.UUID; /** * IdWorkInit @@ -22,7 +23,7 @@ public class IdWorkerInit { /** * MAX_SEQUENCE */ - public static final int MAX_SEQUENCE = 4095; + public static final int MAX_SEQUENCE = 4096; /** * 机器ID和数据中心ID的最大值 @@ -64,6 +65,11 @@ public class IdWorkerInit { */ private IdWorker idWorker; + /** + * 缓存值 + */ + private String cacheValue; + /** * redisTemplate */ @@ -86,8 +92,9 @@ public class IdWorkerInit { } /** - * 初始化 + * 初始化(默认实例化) */ + @PostConstruct public synchronized void init() { //开始处理 boolean result = redisTemplate.execute((RedisCallback) connection -> { @@ -99,10 +106,12 @@ public class IdWorkerInit { //循环 for (int i = 0; i <= MAX_COUNT; i++) { //datacenterId for (int j = 0; j <= MAX_COUNT; j++) { //workerId + //生成一个uuid + cacheValue = UUID.randomUUID().toString(); //生成key String key = cacheRedisProperties.getPrefix().concat(SPLIT).concat(CACHE_NAME).concat(SPLIT).concat(Integer.toString(i)).concat(SPLIT).concat(Integer.toString(j)); //创建锁 - lock = connection.setNX(serializer.serialize(key), serializer.serialize(String.valueOf(new Date().getTime()))); + lock = connection.setNX(serializer.serialize(key), serializer.serialize(cacheValue)); //获得锁成功 if (lock) { //设置超时时间 @@ -150,15 +159,28 @@ public class IdWorkerInit { //生成key String key = cacheRedisProperties.getPrefix().concat(SPLIT).concat(CACHE_NAME).concat(SPLIT).concat(Integer.toString(this.datacenterId)).concat(SPLIT).concat(Integer.toString(this.workerId)); //如果key不存在就创建(方式特殊情况,缓存丢失掉) - connection.setNX(serializer.serialize(key), serializer.serialize(String.valueOf(new Date().getTime()))); - //设置超时时间 - return connection.expire(serializer.serialize(key), EXPIRATION); + connection.setNX(serializer.serialize(key), serializer.serialize(cacheValue)); + //获得值(用于确定锁是否是自己创建的) + String oldCacheVlue = serializer.deserialize(connection.get(serializer.serialize(key))); + //比较(如果值是一样,则代表自己拥有锁,如果值不一样,则代表锁已经被其他进程获取) + if (cacheValue.equals(oldCacheVlue)) { + //设置超时时间 + return connection.expire(serializer.serialize(key), EXPIRATION); + } else { + //重新初始化 + this.init(); + //返回 + return true; + } } finally { connection.close(); } }); //日志输出 log.info("refresh IdWorker success = {} , {} , {}", result, this.datacenterId, this.workerId); + } else { + //重新初始化 + this.init(); } } } diff --git a/udf-starter-id/src/main/java/org/itkk/udf/id/web/IdWorkerController.java b/udf-starter-id/src/main/java/org/itkk/udf/id/web/IdWorkerController.java index baf566f..8d75eff 100644 --- a/udf-starter-id/src/main/java/org/itkk/udf/id/web/IdWorkerController.java +++ b/udf-starter-id/src/main/java/org/itkk/udf/id/web/IdWorkerController.java @@ -8,7 +8,7 @@ package org.itkk.udf.id.web; import org.itkk.udf.core.RestResponse; import org.itkk.udf.core.exception.SystemRuntimeException; -import org.itkk.udf.id.IdWorker; +import org.itkk.udf.id.IdWorkerInit; import org.itkk.udf.id.IdWorkerProperties; import org.itkk.udf.id.domain.Id; import org.springframework.beans.factory.annotation.Autowired; @@ -30,7 +30,7 @@ public class IdWorkerController implements IIdWorkerController { * idWorker */ @Autowired - private IdWorker idWorker; + private IdWorkerInit idWorkerInit; /** * idWorkerProperties @@ -40,7 +40,7 @@ public class IdWorkerController implements IIdWorkerController { @Override public RestResponse get() { - return new RestResponse<>(Long.toString(idWorker.nextId())); + return new RestResponse<>(Long.toString(idWorkerInit.get().nextId())); } @Override @@ -52,13 +52,13 @@ public class IdWorkerController implements IIdWorkerController { //循环生成 List ids = new ArrayList<>(); for (int i = 0; i < count; i++) { - ids.add(Long.toString(idWorker.nextId())); + ids.add(Long.toString(idWorkerInit.get().nextId())); } return new RestResponse<>(ids); } @Override public RestResponse reverse(@PathVariable long id) { - return new RestResponse<>(idWorker.reverse(id)); + return new RestResponse<>(idWorkerInit.get().reverse(id)); } }