diff --git a/.flattened-pom.xml b/.flattened-pom.xml
index ba71703..7a08978 100644
--- a/.flattened-pom.xml
+++ b/.flattened-pom.xml
@@ -16,6 +16,10 @@
han-note-gateway
han-note-oss
han-note-user
+ han-note-kv
+ han-note-distributed-id-generator
+ han-note-note
+ han-note-note/han-note-note-biz
@@ -51,6 +55,11 @@
2.3.3
5.6.227
3.8.0
+ 3.2.2
+ 2.20.0
+ 0.9.16
+ 5.9.0
+ 3.9.4
@@ -215,12 +224,47 @@
feign-form
${feign-form.version}
+
+ commons-io
+ commons-io
+ ${common-io.version}
+
+
+ org.perf4j
+ perf4j
+ ${perf4j.version}
+
+
+ org.apache.curator
+ curator-recipes
+ ${curator-recipes.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+ ${zookeeper.version}
+
com.hanserwei
han-note-user-api
0.0.1-SNAPSHOT
-
+
+ com.hanserwei
+ han-note-kv-api
+ 0.0.1-SNAPSHOT
+
+
+ com.hanserwei
+ han-note-distributed-id-generator-api
+ 0.0.1-SNAPSHOT
+
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+ ${caffeine.version}
+
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/pom.xml b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/pom.xml
index 35905eb..0727648 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/pom.xml
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/pom.xml
@@ -14,14 +14,6 @@
han-note-distributed-id-generator-biz
${project.artifactId}
分布式 ID 生成业务层
-
- 2.4
- 0.9.16
- 1.0.18
- 3.3.0
- 2.6.0
- 3.6.0
-
@@ -50,39 +42,35 @@
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
+
+
+ com.baomidou
+ mybatis-plus-spring-boot3-starter
+
+
+
+ com.alibaba
+ druid-spring-boot-3-starter
+
+
+
+ com.mysql
+ mysql-connector-j
+
+
commons-io
commons-io
- ${common-io.version}
org.perf4j
perf4j
- ${perf4j.version}
-
-
- mysql
- mysql-connector-java
- 8.0.29
-
-
- com.alibaba
- druid
- ${druid.version}
-
- org.mybatis
- mybatis
- ${mybatis.version}
-
-
-
org.apache.curator
curator-recipes
- ${curator-recipes.version}
@@ -103,10 +91,10 @@
+
org.apache.zookeeper
zookeeper
- ${zookeeper.version}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/HannoteDistributedIdGeneratorBizApplication.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/HannoteDistributedIdGeneratorBizApplication.java
index d9bf603..26f84a7 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/HannoteDistributedIdGeneratorBizApplication.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/HannoteDistributedIdGeneratorBizApplication.java
@@ -1,9 +1,15 @@
package com.hanserwei.hannote.distributed.id.generator.biz;
+import com.hanserwei.hannote.distributed.id.generator.biz.config.LeafProperties;
+import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper;
+import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
+@EnableConfigurationProperties(LeafProperties.class)
+@MapperScan(basePackageClasses = IDAllocMapper.class)
public class HannoteDistributedIdGeneratorBizApplication {
public static void main(String[] args) {
SpringApplication.run(HannoteDistributedIdGeneratorBizApplication.class, args);
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafDataSourceConfiguration.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafDataSourceConfiguration.java
new file mode 100644
index 0000000..0adf6c4
--- /dev/null
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafDataSourceConfiguration.java
@@ -0,0 +1,43 @@
+package com.hanserwei.hannote.distributed.id.generator.biz.config;
+
+import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder;
+import jakarta.annotation.PostConstruct;
+import javax.sql.DataSource;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+@Slf4j
+@Configuration
+@RequiredArgsConstructor
+public class LeafDataSourceConfiguration {
+
+ private final LeafProperties leafProperties;
+
+ @PostConstruct
+ void logDataSourceSource() {
+ LeafProperties.Jdbc jdbc = leafProperties.getJdbc();
+ if (StringUtils.hasText(jdbc.getUrl())) {
+ log.info("Leaf JDBC properties detected, will configure DruidDataSource via leaf.jdbc.*");
+ } else {
+ log.info("Leaf JDBC properties not set, relying on default spring.datasource configuration");
+ }
+ }
+
+ @Bean
+ @ConditionalOnMissingBean(DataSource.class)
+ @ConditionalOnProperty(prefix = "leaf.jdbc", name = "url")
+ public DataSource leafDataSource() {
+ LeafProperties.Jdbc jdbc = leafProperties.getJdbc();
+ var dataSource = DruidDataSourceBuilder.create().build();
+ dataSource.setUrl(jdbc.getUrl());
+ dataSource.setUsername(jdbc.getUsername());
+ dataSource.setPassword(jdbc.getPassword());
+ dataSource.setDriverClassName(jdbc.getDriverClassName());
+ return dataSource;
+ }
+}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafProperties.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafProperties.java
new file mode 100644
index 0000000..29f772f
--- /dev/null
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/config/LeafProperties.java
@@ -0,0 +1,72 @@
+package com.hanserwei.hannote.distributed.id.generator.biz.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Getter
+@Setter
+@ConfigurationProperties(prefix = "leaf")
+public class LeafProperties {
+
+ /**
+ * 用于区分不同集群的唯一名称,影响 Snowflake 的 zk 节点路径。
+ */
+ private String name = "leaf";
+
+ private final Segment segment = new Segment();
+ private final Snowflake snowflake = new Snowflake();
+ private final Jdbc jdbc = new Jdbc();
+
+ @Getter
+ @Setter
+ public static class Segment {
+ /**
+ * 是否启用号段模式 ID 生成。
+ */
+ private boolean enable = true;
+ }
+
+ @Getter
+ @Setter
+ public static class Snowflake {
+ /**
+ * 是否启用 Snowflake 模式 ID 生成。
+ */
+ private boolean enable = true;
+
+ /**
+ * Zookeeper 连接地址,示例:127.0.0.1:2181。
+ */
+ private String zkAddress;
+
+ /**
+ * Snowflake 服务监听端口。
+ */
+ private int port = 0;
+ }
+
+ @Getter
+ @Setter
+ public static class Jdbc {
+ /**
+ * JDBC 驱动类名。
+ */
+ private String driverClassName = "com.mysql.cj.jdbc.Driver";
+
+ /**
+ * 数据库连接 URL。
+ */
+ private String url;
+
+ /**
+ * 数据库用户名。
+ */
+ private String username;
+
+ /**
+ * 数据库密码。
+ */
+ private String password;
+ }
+}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/constant/Constants.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/constant/Constants.java
deleted file mode 100644
index 811c6c1..0000000
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/constant/Constants.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.hanserwei.hannote.distributed.id.generator.biz.constant;
-
-public class Constants {
- public static final String LEAF_SEGMENT_ENABLE = "leaf.segment.enable";
- public static final String LEAF_JDBC_URL = "leaf.jdbc.url";
- public static final String LEAF_JDBC_USERNAME = "leaf.jdbc.username";
- public static final String LEAF_JDBC_PASSWORD = "leaf.jdbc.password";
-
- public static final String LEAF_SNOWFLAKE_ENABLE = "leaf.snowflake.enable";
- public static final String LEAF_SNOWFLAKE_PORT = "leaf.snowflake.port";
- public static final String LEAF_SNOWFLAKE_ZK_ADDRESS = "leaf.snowflake.zk.address";
-}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/PropertyFactory.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/PropertyFactory.java
deleted file mode 100644
index d3e5526..0000000
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/PropertyFactory.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.hanserwei.hannote.distributed.id.generator.biz.core.common;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Properties;
-
-public class PropertyFactory {
- private static final Logger logger = LoggerFactory.getLogger(PropertyFactory.class);
- private static final Properties prop = new Properties();
- static {
- try {
- prop.load(PropertyFactory.class.getClassLoader().getResourceAsStream("leaf.properties"));
- } catch (IOException e) {
- logger.warn("Load Properties Ex", e);
- }
- }
- public static Properties getProperties() {
- return prop;
- }
-}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Result.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Result.java
index 9485370..d2268b3 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Result.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Result.java
@@ -1,5 +1,10 @@
package com.hanserwei.hannote.distributed.id.generator.biz.core.common;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
public class Result {
private long id;
private Status status;
@@ -12,22 +17,6 @@ public class Result {
this.status = status;
}
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public Status getStatus() {
- return status;
- }
-
- public void setStatus(Status status) {
- this.status = status;
- }
-
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Result{");
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Utils.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Utils.java
index 53156a5..8ffc58e 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Utils.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/common/Utils.java
@@ -19,7 +19,7 @@ public class Utils {
try {
List ipList = getHostAddress(null);
// default the first
- ip = (!ipList.isEmpty()) ? ipList.get(0) : "";
+ ip = (!ipList.isEmpty()) ? ipList.getFirst() : "";
} catch (Exception ex) {
ip = "";
logger.warn("Utils get IP warn", ex);
@@ -32,7 +32,7 @@ public class Utils {
interfaceName = interfaceName.trim();
try {
List ipList = getHostAddress(interfaceName);
- ip = (!ipList.isEmpty()) ? ipList.get(0) : "";
+ ip = (!ipList.isEmpty()) ? ipList.getFirst() : "";
} catch (Exception ex) {
ip = "";
logger.warn("Utils get IP warn", ex);
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/IDAllocMapper.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/IDAllocMapper.java
index c36cbdf..f0035ff 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/IDAllocMapper.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/IDAllocMapper.java
@@ -1,10 +1,16 @@
package com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao;
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.model.LeafAlloc;
-import org.apache.ibatis.annotations.*;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
import java.util.List;
+@Mapper
public interface IDAllocMapper {
@Select("SELECT biz_tag, max_id, step, update_time FROM leaf_alloc")
@@ -27,7 +33,7 @@ public interface IDAllocMapper {
@Update("UPDATE leaf_alloc SET max_id = max_id + step WHERE biz_tag = #{tag}")
void updateMaxId(@Param("tag") String tag);
- @Update("UPDATE leaf_alloc SET max_id = max_id + #{step} WHERE biz_tag = #{key}")
+ @Update("UPDATE leaf_alloc SET max_id = max_id + #{leafAlloc.step} WHERE biz_tag = #{leafAlloc.key}")
void updateMaxIdByCustomStep(@Param("leafAlloc") LeafAlloc leafAlloc);
@Select("SELECT biz_tag FROM leaf_alloc")
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/impl/IDAllocDaoImpl.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/impl/IDAllocDaoImpl.java
index bdd36fb..4f054bd 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/impl/IDAllocDaoImpl.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/segment/dao/impl/IDAllocDaoImpl.java
@@ -1,75 +1,50 @@
package com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.impl;
-
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocDao;
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper;
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.model.LeafAlloc;
-import org.apache.ibatis.mapping.Environment;
-import org.apache.ibatis.session.Configuration;
-import org.apache.ibatis.session.SqlSession;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.apache.ibatis.session.SqlSessionFactoryBuilder;
-import org.apache.ibatis.transaction.TransactionFactory;
-import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
-import javax.sql.DataSource;
import java.util.List;
+@Slf4j
+@Primary
+@Repository
+@RequiredArgsConstructor
public class IDAllocDaoImpl implements IDAllocDao {
- SqlSessionFactory sqlSessionFactory;
-
- public IDAllocDaoImpl(DataSource dataSource) {
- TransactionFactory transactionFactory = new JdbcTransactionFactory();
- Environment environment = new Environment("development", transactionFactory, dataSource);
- Configuration configuration = new Configuration(environment);
- configuration.addMapper(IDAllocMapper.class);
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
+ private final IDAllocMapper idAllocMapper;
+ @PostConstruct
+ void logInit() {
+ log.info("IDAllocDaoImpl initialized as primary IDAllocDao implementation");
}
@Override
public List getAllLeafAllocs() {
- SqlSession sqlSession = sqlSessionFactory.openSession(false);
- try {
- return sqlSession.selectList("com.hanserwei.hannote.segment.dao.IDAllocMapper.getAllLeafAllocs");
- } finally {
- sqlSession.close();
- }
+ return idAllocMapper.getAllLeafAllocs();
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public LeafAlloc updateMaxIdAndGetLeafAlloc(String tag) {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- sqlSession.update("com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper.updateMaxId", tag);
- LeafAlloc result = sqlSession.selectOne("com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper.getLeafAlloc", tag);
- sqlSession.commit();
- return result;
- } finally {
- sqlSession.close();
- }
+ idAllocMapper.updateMaxId(tag);
+ return idAllocMapper.getLeafAlloc(tag);
}
@Override
+ @Transactional(rollbackFor = Exception.class)
public LeafAlloc updateMaxIdByCustomStepAndGetLeafAlloc(LeafAlloc leafAlloc) {
- SqlSession sqlSession = sqlSessionFactory.openSession();
- try {
- sqlSession.update("com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper.updateMaxIdByCustomStep", leafAlloc);
- LeafAlloc result = sqlSession.selectOne("com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper.getLeafAlloc", leafAlloc.getKey());
- sqlSession.commit();
- return result;
- } finally {
- sqlSession.close();
- }
+ idAllocMapper.updateMaxIdByCustomStep(leafAlloc);
+ return idAllocMapper.getLeafAlloc(leafAlloc.getKey());
}
@Override
public List getAllTags() {
- SqlSession sqlSession = sqlSessionFactory.openSession(false);
- try {
- return sqlSession.selectList("com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocMapper.getAllTags");
- } finally {
- sqlSession.close();
- }
+ return idAllocMapper.getAllTags();
}
}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeIDGenImpl.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeIDGenImpl.java
index e615cc7..08f38d5 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeIDGenImpl.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeIDGenImpl.java
@@ -31,22 +31,23 @@ public class SnowflakeIDGenImpl implements IDGen {
private long lastTimestamp = -1L;
private static final Random RANDOM = new Random();
- public SnowflakeIDGenImpl(String zkAddress, int port) {
+ public SnowflakeIDGenImpl(String leafName, String zkAddress, int port) {
//Thu Nov 04 2010 09:42:54 GMT+0800 (中国标准时间)
- this(zkAddress, port, 1288834974657L);
+ this(leafName, zkAddress, port, 1288834974657L);
}
/**
+ * @param leafName 区分集群的唯一名称
* @param zkAddress zk地址
* @param port snowflake监听端口
* @param twepoch 起始的时间戳
*/
- public SnowflakeIDGenImpl(String zkAddress, int port, long twepoch) {
+ public SnowflakeIDGenImpl(String leafName, String zkAddress, int port, long twepoch) {
this.twepoch = twepoch;
Preconditions.checkArgument(timeGen() > twepoch, "Snowflake not support twepoch gt currentTime");
final String ip = Utils.getIp();
- SnowflakeZookeeperHolder holder = new SnowflakeZookeeperHolder(ip, String.valueOf(port), zkAddress);
- LOGGER.info("twepoch:{} ,ip:{} ,zkAddress:{} port:{}", twepoch, ip, zkAddress, port);
+ SnowflakeZookeeperHolder holder = new SnowflakeZookeeperHolder(leafName, ip, String.valueOf(port), zkAddress);
+ LOGGER.info("twepoch:{} ,leafName:{} ,ip:{} ,zkAddress:{} port:{}", twepoch, leafName, ip, zkAddress, port);
boolean initFlag = holder.init();
if (initFlag) {
workerId = holder.getWorkerID();
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeZookeeperHolder.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeZookeeperHolder.java
index b25648f..1a97c3e 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeZookeeperHolder.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/core/snowflake/SnowflakeZookeeperHolder.java
@@ -3,7 +3,6 @@ package com.hanserwei.hannote.distributed.id.generator.biz.core.snowflake;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
-import com.hanserwei.hannote.distributed.id.generator.biz.core.common.PropertyFactory;
import com.hanserwei.hannote.distributed.id.generator.biz.core.snowflake.exception.CheckLastTimeException;
import org.apache.commons.io.FileUtils;
import org.apache.curator.RetryPolicy;
@@ -27,18 +26,22 @@ import java.util.concurrent.TimeUnit;
public class SnowflakeZookeeperHolder {
private static final Logger LOGGER = LoggerFactory.getLogger(SnowflakeZookeeperHolder.class);
+ private final String leafName;
+ private final String pathForever;//保存所有数据持久的节点
+ private final String propPath;
private String zk_AddressNode = null;//保存自身的key ip:port-000000001
private String listenAddress = null;//保存自身的key ip:port
private int workerID;
- private static final String PREFIX_ZK_PATH = "/snowflake/" + PropertyFactory.getProperties().getProperty("leaf.name");
- private static final String PROP_PATH = System.getProperty("java.io.tmpdir") + File.separator + PropertyFactory.getProperties().getProperty("leaf.name") + "/leafconf/{port}/workerID.properties";
- private static final String PATH_FOREVER = PREFIX_ZK_PATH + "/forever";//保存所有数据持久的节点
private String ip;
private String port;
private String connectionString;
private long lastUpdateTime;
- public SnowflakeZookeeperHolder(String ip, String port, String connectionString) {
+ public SnowflakeZookeeperHolder(String leafName, String ip, String port, String connectionString) {
+ this.leafName = leafName;
+ String prefixZkPath = "/snowflake/" + leafName;
+ this.pathForever = prefixZkPath + "/forever";
+ this.propPath = System.getProperty("java.io.tmpdir") + File.separator + leafName + "/leafconf/{port}/workerID.properties";
this.ip = ip;
this.port = port;
this.listenAddress = ip + ":" + port;
@@ -47,22 +50,23 @@ public class SnowflakeZookeeperHolder {
public boolean init() {
try {
+ LOGGER.info("Initializing SnowflakeZookeeperHolder for leafName={}, listenAddress={}, zkAddress={}", leafName, listenAddress, connectionString);
CuratorFramework curator = createWithOptions(connectionString, new RetryUntilElapsed(1000, 4), 10000, 6000);
curator.start();
- Stat stat = curator.checkExists().forPath(PATH_FOREVER);
+ Stat stat = curator.checkExists().forPath(pathForever);
if (stat == null) {
//不存在根节点,机器第一次启动,创建/snowflake/ip:port-000000000,并上传数据
zk_AddressNode = createNode(curator);
//worker id 默认是0
updateLocalWorkerID(workerID);
//定时上报本机时间给forever节点
- ScheduledUploadData(curator, zk_AddressNode);
+ scheduleUploadData(curator, zk_AddressNode);
return true;
} else {
Map nodeMap = Maps.newHashMap();//ip:port->00001
Map realNode = Maps.newHashMap();//ip:port->(ipport-000001)
//存在根节点,先检查是否有属于自己的根节点
- List keys = curator.getChildren().forPath(PATH_FOREVER);
+ List keys = curator.getChildren().forPath(pathForever);
for (String key : keys) {
String[] nodeKey = key.split("-");
realNode.put(nodeKey[0], key);
@@ -71,7 +75,7 @@ public class SnowflakeZookeeperHolder {
Integer workerid = nodeMap.get(listenAddress);
if (workerid != null) {
//有自己的节点,zk_AddressNode=ip:port
- zk_AddressNode = PATH_FOREVER + "/" + realNode.get(listenAddress);
+ zk_AddressNode = pathForever + "/" + realNode.get(listenAddress);
workerID = workerid;//启动worder时使用会使用
if (!checkInitTimeStamp(curator, zk_AddressNode)) {
throw new CheckLastTimeException("init timestamp check error,forever node timestamp gt this node time");
@@ -95,7 +99,7 @@ public class SnowflakeZookeeperHolder {
LOGGER.error("Start node ERROR {}", e);
try {
Properties properties = new Properties();
- properties.load(new FileInputStream(new File(PROP_PATH.replace("{port}", port + ""))));
+ properties.load(new FileInputStream(new File(propPath.replace("{port}", port + ""))));
workerID = Integer.valueOf(properties.getProperty("workerID"));
LOGGER.warn("START FAILED ,use local node file properties workerID-{}", workerID);
} catch (Exception e1) {
@@ -107,10 +111,10 @@ public class SnowflakeZookeeperHolder {
}
private void doService(CuratorFramework curator) {
- ScheduledUploadData(curator, zk_AddressNode);// /snowflake_forever/ip:port-000000001
+ scheduleUploadData(curator, zk_AddressNode);// /snowflake_forever/ip:port-000000001
}
- private void ScheduledUploadData(final CuratorFramework curator, final String zk_AddressNode) {
+ private void scheduleUploadData(final CuratorFramework curator, final String zk_AddressNode) {
Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
@@ -143,7 +147,7 @@ public class SnowflakeZookeeperHolder {
*/
private String createNode(CuratorFramework curator) throws Exception {
try {
- return curator.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(PATH_FOREVER + "/" + listenAddress + "-", buildData().getBytes());
+ return curator.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT_SEQUENTIAL).forPath(pathForever + "/" + listenAddress + "-", buildData().getBytes());
} catch (Exception e) {
LOGGER.error("create node error msg {} ", e.getMessage());
throw e;
@@ -186,7 +190,7 @@ public class SnowflakeZookeeperHolder {
* @param workerID
*/
private void updateLocalWorkerID(int workerID) {
- File leafConfFile = new File(PROP_PATH.replace("{port}", port));
+ File leafConfFile = new File(propPath.replace("{port}", port));
boolean exists = leafConfFile.exists();
LOGGER.info("file exists status is {}", exists);
if (exists) {
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/model/SegmentBufferView.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/model/SegmentBufferView.java
index a45bcb6..9028e5a 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/model/SegmentBufferView.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/model/SegmentBufferView.java
@@ -1,5 +1,10 @@
package com.hanserwei.hannote.distributed.id.generator.biz.model;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
public class SegmentBufferView {
private String key;
private long value0;
@@ -13,83 +18,4 @@ public class SegmentBufferView {
private boolean nextReady;
private boolean initOk;
- public String getKey() {
- return key;
- }
-
- public void setKey(String key) {
- this.key = key;
- }
-
- public long getValue1() {
- return value1;
- }
-
- public void setValue1(long value1) {
- this.value1 = value1;
- }
-
- public int getStep1() {
- return step1;
- }
-
- public void setStep1(int step1) {
- this.step1 = step1;
- }
-
- public long getMax1() {
- return max1;
- }
-
- public void setMax1(long max1) {
- this.max1 = max1;
- }
-
- public long getValue0() {
- return value0;
- }
-
- public void setValue0(long value0) {
- this.value0 = value0;
- }
-
- public int getStep0() {
- return step0;
- }
-
- public void setStep0(int step0) {
- this.step0 = step0;
- }
-
- public long getMax0() {
- return max0;
- }
-
- public void setMax0(long max0) {
- this.max0 = max0;
- }
-
- public int getPos() {
- return pos;
- }
-
- public void setPos(int pos) {
- this.pos = pos;
- }
-
- public boolean isNextReady() {
- return nextReady;
- }
-
- public void setNextReady(boolean nextReady) {
- this.nextReady = nextReady;
- }
-
- public boolean isInitOk() {
- return initOk;
- }
-
- public void setInitOk(boolean initOk) {
- this.initOk = initOk;
- }
}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SegmentService.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SegmentService.java
index b1c7617..6390dd9 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SegmentService.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SegmentService.java
@@ -1,67 +1,51 @@
package com.hanserwei.hannote.distributed.id.generator.biz.service;
-import com.alibaba.druid.pool.DruidDataSource;
-import com.hanserwei.hannote.distributed.id.generator.biz.constant.Constants;
+import com.hanserwei.hannote.distributed.id.generator.biz.config.LeafProperties;
import com.hanserwei.hannote.distributed.id.generator.biz.core.IDGen;
-import com.hanserwei.hannote.distributed.id.generator.biz.core.common.PropertyFactory;
import com.hanserwei.hannote.distributed.id.generator.biz.core.common.Result;
import com.hanserwei.hannote.distributed.id.generator.biz.core.common.ZeroIDGen;
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.SegmentIDGenImpl;
import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.IDAllocDao;
-import com.hanserwei.hannote.distributed.id.generator.biz.core.segment.dao.impl.IDAllocDaoImpl;
-import com.hanserwei.hannote.distributed.id.generator.biz.exception.InitException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
-import java.sql.SQLException;
-import java.util.Properties;
-
-@Service("SegmentService")
+@Slf4j
+@Service
+@RequiredArgsConstructor
public class SegmentService {
- private Logger logger = LoggerFactory.getLogger(SegmentService.class);
+
+ private final LeafProperties leafProperties;
+ private final IDAllocDao idAllocDao;
private IDGen idGen;
- private DruidDataSource dataSource;
- public SegmentService() throws SQLException, InitException {
- Properties properties = PropertyFactory.getProperties();
- boolean flag = Boolean.parseBoolean(properties.getProperty(Constants.LEAF_SEGMENT_ENABLE, "true"));
- if (flag) {
- // Config dataSource
- dataSource = new DruidDataSource();
- dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
- dataSource.setUrl(properties.getProperty(Constants.LEAF_JDBC_URL));
- dataSource.setUsername(properties.getProperty(Constants.LEAF_JDBC_USERNAME));
- dataSource.setPassword(properties.getProperty(Constants.LEAF_JDBC_PASSWORD));
- dataSource.setValidationQuery("select 1");
- dataSource.init();
-
- // Config Dao
- IDAllocDao dao = new IDAllocDaoImpl(dataSource);
-
- // Config ID Gen
- idGen = new SegmentIDGenImpl();
- ((SegmentIDGenImpl) idGen).setDao(dao);
- if (idGen.init()) {
- logger.info("Segment Service Init Successfully");
+ @PostConstruct
+ public void init() {
+ if (leafProperties.getSegment().isEnable()) {
+ SegmentIDGenImpl segmentIDGen = new SegmentIDGenImpl();
+ segmentIDGen.setDao(idAllocDao);
+ if (segmentIDGen.init()) {
+ this.idGen = segmentIDGen;
+ log.info("Segment Service Init Successfully");
} else {
- throw new InitException("Segment Service Init Fail");
+ throw new IllegalStateException("Segment Service Init Fail");
}
} else {
- idGen = new ZeroIDGen();
- logger.info("Zero ID Gen Service Init Successfully");
+ this.idGen = new ZeroIDGen();
+ log.info("Segment Service disabled, Zero ID Gen Service Init Successfully");
}
}
public Result getId(String key) {
+ if (idGen == null) {
+ throw new IllegalStateException("Segment Service not initialized");
+ }
return idGen.get(key);
}
public SegmentIDGenImpl getIdGen() {
- if (idGen instanceof SegmentIDGenImpl) {
- return (SegmentIDGenImpl) idGen;
- }
- return null;
+ return idGen instanceof SegmentIDGenImpl ? (SegmentIDGenImpl) idGen : null;
}
}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SnowflakeService.java b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SnowflakeService.java
index c4f395c..df16c56 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SnowflakeService.java
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/java/com/hanserwei/hannote/distributed/id/generator/biz/service/SnowflakeService.java
@@ -1,44 +1,53 @@
package com.hanserwei.hannote.distributed.id.generator.biz.service;
-
-import com.hanserwei.hannote.distributed.id.generator.biz.constant.Constants;
+import com.hanserwei.hannote.distributed.id.generator.biz.config.LeafProperties;
import com.hanserwei.hannote.distributed.id.generator.biz.core.IDGen;
-import com.hanserwei.hannote.distributed.id.generator.biz.core.common.PropertyFactory;
import com.hanserwei.hannote.distributed.id.generator.biz.core.common.Result;
import com.hanserwei.hannote.distributed.id.generator.biz.core.common.ZeroIDGen;
import com.hanserwei.hannote.distributed.id.generator.biz.core.snowflake.SnowflakeIDGenImpl;
-import com.hanserwei.hannote.distributed.id.generator.biz.exception.InitException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
-import java.util.Properties;
-
-@Service("SnowflakeService")
+@Slf4j
+@Service
+@RequiredArgsConstructor
public class SnowflakeService {
- private Logger logger = LoggerFactory.getLogger(SnowflakeService.class);
+
+ private final LeafProperties leafProperties;
private IDGen idGen;
- public SnowflakeService() throws InitException {
- Properties properties = PropertyFactory.getProperties();
- boolean flag = Boolean.parseBoolean(properties.getProperty(Constants.LEAF_SNOWFLAKE_ENABLE, "true"));
- if (flag) {
- String zkAddress = properties.getProperty(Constants.LEAF_SNOWFLAKE_ZK_ADDRESS);
- int port = Integer.parseInt(properties.getProperty(Constants.LEAF_SNOWFLAKE_PORT));
- idGen = new SnowflakeIDGenImpl(zkAddress, port);
- if(idGen.init()) {
- logger.info("Snowflake Service Init Successfully");
+ @PostConstruct
+ public void init() {
+ if (leafProperties.getSnowflake().isEnable()) {
+ String zkAddress = leafProperties.getSnowflake().getZkAddress();
+ if (!StringUtils.hasText(zkAddress)) {
+ throw new IllegalStateException("Snowflake Service Init Fail: zk address is required");
+ }
+ int port = leafProperties.getSnowflake().getPort();
+ if (port <= 0) {
+ throw new IllegalStateException("Snowflake Service Init Fail: port must be positive");
+ }
+ SnowflakeIDGenImpl snowflakeIDGen = new SnowflakeIDGenImpl(leafProperties.getName(), zkAddress, port);
+ if (snowflakeIDGen.init()) {
+ this.idGen = snowflakeIDGen;
+ log.info("Snowflake Service Init Successfully with zkAddress={} and port={}", zkAddress, port);
} else {
- throw new InitException("Snowflake Service Init Fail");
+ throw new IllegalStateException("Snowflake Service Init Fail");
}
} else {
- idGen = new ZeroIDGen();
- logger.info("Zero ID Gen Service Init Successfully");
+ this.idGen = new ZeroIDGen();
+ log.info("Snowflake Service disabled, Zero ID Gen Service Init Successfully");
}
}
public Result getId(String key) {
+ if (idGen == null) {
+ throw new IllegalStateException("Snowflake Service not initialized");
+ }
return idGen.get(key);
}
}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-dev.yml b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-dev.yml
index 88ff417..154530a 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-dev.yml
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-dev.yml
@@ -1,5 +1,6 @@
spring:
- cassandra:
- keyspace-name: hannote
- contact-points: 127.0.0.1
- port: 9042
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://127.0.0.1:3306/leaf?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
+ username: root
+ password: mysql
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-prod.yml b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-prod.yml
index e69de29..df7bd29 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-prod.yml
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application-prod.yml
@@ -0,0 +1,11 @@
+spring:
+ datasource:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ url: ${LEAF_DB_URL:jdbc:mysql://db-host:3306/leaf?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai}
+ username: ${LEAF_DB_USERNAME:leaf_user}
+ password: ${LEAF_DB_PASSWORD:leaf_password}
+
+leaf:
+ snowflake:
+ zk-address: "${LEAF_SNOWFLAKE_ZK_ADDRESS:zk.example.com:2181}"
+ port: ${LEAF_SNOWFLAKE_PORT:2222}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application.yml b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application.yml
index c828c64..6e5b49b 100644
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application.yml
+++ b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/application.yml
@@ -4,3 +4,22 @@ server:
spring:
profiles:
active: dev # 默认激活 dev 本地开发环境
+ datasource:
+ driver-class-name: ${LEAF_JDBC_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver}
+ url: ${LEAF_JDBC_URL:jdbc:mysql://127.0.0.1:3306/leaf?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai}
+ username: ${LEAF_JDBC_USERNAME:root}
+ password: ${LEAF_JDBC_PASSWORD:mysql}
+
+leaf:
+ name: ${LEAF_NAME:han-note-leaf}
+ jdbc:
+ driver-class-name: ${LEAF_JDBC_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver}
+ url: ${LEAF_JDBC_URL:jdbc:mysql://127.0.0.1:3306/leaf?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai}
+ username: ${LEAF_JDBC_USERNAME:root}
+ password: ${LEAF_JDBC_PASSWORD:mysql}
+ segment:
+ enable: ${LEAF_SEGMENT_ENABLE:true}
+ snowflake:
+ enable: ${LEAF_SNOWFLAKE_ENABLE:true}
+ zk-address: "${LEAF_SNOWFLAKE_ZK_ADDRESS:127.0.0.1:2181}"
+ port: ${LEAF_SNOWFLAKE_PORT:2222}
diff --git a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/leaf.properties b/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/leaf.properties
deleted file mode 100644
index 2fd6562..0000000
--- a/han-note-distributed-id-generator/han-note-distributed-id-generator-biz/src/main/resources/leaf.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-leaf.name=com.sankuai.leaf.opensource.test
-leaf.segment.enable=true
-leaf.jdbc.url=jdbc:mysql://127.0.0.1:3306/leaf?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
-leaf.jdbc.username=root
-leaf.jdbc.password=mysql
-
-# ???? snowflake ??
-leaf.snowflake.enable=true
-# snowflake ???? zk ??
-leaf.snowflake.zk.address=127.0.0.1:2181
-# snowflake ??????????
-leaf.snowflake.port=2222
diff --git a/pom.xml b/pom.xml
index 075e821..010df35 100755
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,10 @@
5.6.227
3.8.0
3.2.2
+ 2.20.0
+ 0.9.16
+ 5.9.0
+ 3.9.4
@@ -220,6 +224,26 @@
feign-form
${feign-form.version}
+
+ commons-io
+ commons-io
+ ${common-io.version}
+
+
+ org.perf4j
+ perf4j
+ ${perf4j.version}
+
+
+ org.apache.curator
+ curator-recipes
+ ${curator-recipes.version}
+
+
+ org.apache.zookeeper
+ zookeeper
+ ${zookeeper.version}
+
com.hanserwei
han-note-user-api