Initial commit: reorganized source tree

- backend/: 13 Maven modules (cw-elevator-application, cloudwalk-cloud, intelligent-cwoscomponent, ninca-crk, etc.)
- frontend/: 4 Vue projects (elevator-front, cwos-portal, alarm-front, front_acs) + decompiled + scripts
- scripts/: build, test-env, tools (Docker Compose, service templates, API parity)
- docs/: AGENTS.md, superpowers specs, architecture docs
- .gitignore: standard Java/Maven exclusions

Moved from legacy maven-*/ root layout to backend/ organized structure.
This commit is contained in:
hpd840321
2026-05-09 09:00:12 +08:00
commit 7b2bd307f1
7260 changed files with 612980 additions and 0 deletions
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.cloudwalk.cloud</groupId>
<artifactId>cloudwalk-cloud-common</artifactId>
<version>3.7.2-Brussels-SRX</version>
<relativePath>../cloudwalk-cloud-common/pom.xml</relativePath>
</parent>
<artifactId>cloudwalk-common-serial</artifactId>
<packaging>jar</packaging>
<name>cloudwalk-common-serial</name>
<description>源码来自 反1 zip。</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>cn.cloudwalk.cloud</groupId>
<artifactId>cloudwalk-common-result</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,57 @@
package cn.cloudwalk.serial.autoconfig.serial;
import cn.cloudwalk.serial.code.AbstractGeneralCode;
import cn.cloudwalk.serial.code.GeneralSerial;
import cn.cloudwalk.serial.code.GeneralSerialCode;
import cn.cloudwalk.serial.code.MacGeneralSerial;
import cn.cloudwalk.serial.code.RedisGeneralCode;
import cn.cloudwalk.serial.redis.CloudwalkRedisService;
import cn.cloudwalk.serial.strategy.ServerIdStrategyBeanConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
@Import({ServerIdStrategyBeanConfig.class, CloudwalkSnowflakeConfiguration.class})
@EnableConfigurationProperties({CloudwalkSerialProperties.class})
@ConditionalOnProperty(prefix = "cloudwalk.serial", value = {"enabled"}, havingValue = "true", matchIfMissing = true)
public class CloudwalkSerialAutoConfiguration {
@Autowired(required = false)
private RedisTemplate<String, String> redisTemplate;
@Autowired
private CloudwalkSerialProperties serialProperties;
@Bean
@ConditionalOnMissingBean
public CloudwalkRedisService cloudwalkRedisService() {
if ("redis".equals(this.serialProperties.getSerialType()))
;
return null;
}
@Bean
public GeneralSerial generalSerial() {
if ("redis".equals(this.serialProperties.getSerialType())) {
CloudwalkRedisService redisService = new CloudwalkRedisService();
redisService.setRedisTemplate(this.redisTemplate);
RedisGeneralCode redisGeneralCode = new RedisGeneralCode(this.serialProperties.getSerialRedisKey());
redisGeneralCode.setRedisService(redisService);
return (GeneralSerial) redisGeneralCode;
}
return (GeneralSerial) new MacGeneralSerial();
}
@Bean({ "generalSerialCode" })
public AbstractGeneralCode abstractGeneralCode() {
GeneralSerialCode generalSerialCode = new GeneralSerialCode(generalSerial());
generalSerialCode.setSerialLength(this.serialProperties.getSerialLength());
return (AbstractGeneralCode) generalSerialCode;
}
}
@@ -0,0 +1,54 @@
package cn.cloudwalk.serial.autoconfig.serial;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "cloudwalk.serial")
public class CloudwalkSerialProperties {
public static final String TARGET_NAME = "cloudwalk.serial";
private boolean enable = true;
private String serialRedisKey;
private String serialType;
private int serialLength = 8;
private ServerIdStrategyConf serverIdStrategy;
public void setSerialRedisKey(String serialRedisKey) {
this.serialRedisKey = serialRedisKey;
}
public String getSerialRedisKey() {
return this.serialRedisKey;
}
public void setSerialType(String serialType) {
this.serialType = serialType;
}
public String getSerialType() {
return this.serialType;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public boolean isEnable() {
return this.enable;
}
public void setSerialLength(int serialLength) {
this.serialLength = serialLength;
}
public int getSerialLength() {
return this.serialLength;
}
public ServerIdStrategyConf getServerIdStrategy() {
return this.serverIdStrategy;
}
public void setServerIdStrategy(ServerIdStrategyConf serverIdStrategy) {
this.serverIdStrategy = serverIdStrategy;
}
}
@@ -0,0 +1,22 @@
package cn.cloudwalk.serial.autoconfig.serial;
import cn.cloudwalk.cloud.serial.UUIDSerial;
import cn.cloudwalk.serial.strategy.ServerIdStrategy;
import cn.cloudwalk.serial.worker.SnowFlakeSerialCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
public class CloudwalkSnowflakeConfiguration {
@Autowired(required = false)
private RedisTemplate<String, String> redisTemplate;
@Bean
@ConditionalOnMissingBean({ UUIDSerial.class })
public UUIDSerial snowFlakeSerialCode(ServerIdStrategy serverIdStrategy) {
return (UUIDSerial) new SnowFlakeSerialCode(this.redisTemplate, serverIdStrategy);
}
}
@@ -0,0 +1,22 @@
package cn.cloudwalk.serial.autoconfig.serial;
public class ServerIdStrategyConf {
private String code;
private String className;
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
public String getClassName() {
return this.className;
}
public void setClassName(String className) {
this.className = className;
}
}
@@ -0,0 +1,26 @@
package cn.cloudwalk.serial.code;
public abstract class AbstractGeneralCode {
private GeneralSerial generalSerial;
private int serialLength;
public void setSerialLength(int serialLength) {
this.serialLength = serialLength;
}
public void setGeneralBusinessCode(GeneralSerial generalSerial) {
this.generalSerial = generalSerial;
}
public String generalCode(String prefix, Integer length) {
Integer serial = this.generalSerial.generalSerial();
return prefix + warpSerial(serial, length);
}
public String generalCode() {
Integer serial = this.generalSerial.generalSerial();
return warpSerial(serial, Integer.valueOf(this.serialLength));
}
protected abstract String warpSerial(Integer paramInteger1, Integer paramInteger2);
}
@@ -0,0 +1,5 @@
package cn.cloudwalk.serial.code;
public interface GeneralSerial {
Integer generalSerial();
}
@@ -0,0 +1,35 @@
package cn.cloudwalk.serial.code;
import org.springframework.util.Assert;
public class GeneralSerialCode extends AbstractGeneralCode {
public GeneralSerialCode(GeneralSerial generalSerial) {
Assert.notNull(generalSerial, "generalBusinessCode is not null");
setGeneralBusinessCode(generalSerial);
}
protected String warpSerial(Integer serial, Integer length) {
if (length.intValue() <= 0) {
throw new IllegalArgumentException("length must more than 0");
}
StringBuilder sb = new StringBuilder();
if (serial.intValue() == 0) {
for (int i = 0; i < length.intValue(); i++) {
sb.append("0");
}
} else {
String ser = String.valueOf(serial);
if (ser.length() >= length.intValue()) {
sb.append(ser);
} else {
for (int i = ser.length(); i < length.intValue(); i++) {
sb.append("0");
}
sb.append(ser);
}
}
return sb.toString();
}
}
@@ -0,0 +1,24 @@
package cn.cloudwalk.serial.code;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MacGeneralSerial implements GeneralSerial {
private Lock lock = new ReentrantLock();
private volatile Integer serial = Integer.valueOf(0);
public Integer generalSerial() {
return serial();
}
private Integer serial() {
try {
this.lock.lock();
Integer integer1 = this.serial, integer2 = this.serial = Integer.valueOf(this.serial.intValue() + 1);
} finally {
this.lock.unlock();
}
return this.serial;
}
}
@@ -0,0 +1,30 @@
package cn.cloudwalk.serial.code;
import cn.cloudwalk.serial.redis.CloudwalkRedisService;
import org.springframework.util.StringUtils;
public class RedisGeneralCode implements GeneralSerial {
private CloudwalkRedisService redisService;
private String redisKey;
public RedisGeneralCode(String redisKey) {
if (StringUtils.isEmpty(redisKey)) {
this.redisKey = "CLODWALK-DEFAULT-GENERAL-SERIAL-KEY";
} else {
this.redisKey = redisKey;
}
}
public void setRedisService(CloudwalkRedisService redisService) {
this.redisService = redisService;
}
public Integer generalSerial() {
return serial();
}
private Integer serial() {
long serial = this.redisService.incr(this.redisKey);
return Integer.valueOf((int) serial);
}
}
@@ -0,0 +1,44 @@
package cn.cloudwalk.serial.redis;
import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.RedisTemplate;
public class CloudwalkRedisService {
private RedisTemplate<String, String> redisTemplate;
public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public String get(String key) {
return (String) this.redisTemplate.opsForValue().get(key);
}
public void set(String key, String value, long timeout) {
this.redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
}
public void set(String key, String value) {
set(key, value, 86400L);
}
public void setBlank(String key) {
set(key, "", 86400L);
}
public long incr(String key) {
return incrBy(key, 1L);
}
public long incrBy(String key, long delta) {
return this.redisTemplate.opsForValue().increment(key, delta).longValue();
}
public boolean lock(String key, String value) {
return this.redisTemplate.opsForValue().setIfAbsent(key, value).booleanValue();
}
public void unLock(String key) {
this.redisTemplate.delete(key);
}
}
@@ -0,0 +1,326 @@
package cn.cloudwalk.serial.redis;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public final class RedisComponent {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
public Set<Object> keys(Object prefix) {
return this.redisTemplate.keys(prefix);
}
public List<Object> multiGet(Set<Object> keys) {
return this.redisTemplate.opsForValue().multiGet(keys);
}
public boolean expire(String key, long time) {
try {
if (time > 0L) {
this.redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
this.logger.error("expire error:", e);
return false;
}
}
public long getExpire(String key) {
return this.redisTemplate.getExpire(key, TimeUnit.SECONDS).longValue();
}
public boolean hasKey(String key) {
try {
return this.redisTemplate.hasKey(key).booleanValue();
} catch (Exception e) {
this.logger.error("hasKey error:", e);
return false;
}
}
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
this.redisTemplate.delete(key[0]);
} else {
this.redisTemplate.delete(key);
}
}
}
public Object get(String key) {
return (key == null) ? null : this.redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value) {
try {
this.redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
this.logger.error("set error:", e);
return false;
}
}
public boolean set(String key, Object value, long time) {
try {
if (time > 0L) {
this.redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
this.logger.error("set error:", e);
return false;
}
}
public long incr(String key, long delta) {
if (delta < 0L) {
throw new RuntimeException("递增因子必须大于0");
}
return this.redisTemplate.opsForValue().increment(key, delta).longValue();
}
public long decr(String key, long delta) {
if (delta < 0L) {
throw new RuntimeException("递减因子必须大于0");
}
return this.redisTemplate.opsForValue().increment(key, -delta).longValue();
}
public Object hget(String key, String item) {
return this.redisTemplate.opsForHash().get(key, item);
}
public Map<Object, Object> hmget(String key) {
return this.redisTemplate.opsForHash().entries(key);
}
public boolean hmset(String key, Map<String, Object> map) {
try {
this.redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
this.logger.error("hmset error:", e);
return false;
}
}
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
this.redisTemplate.opsForHash().putAll(key, map);
if (time > 0L) {
expire(key, time);
}
return true;
} catch (Exception e) {
this.logger.error("hmset error:", e);
return false;
}
}
public boolean hset(String key, String item, Object value) {
try {
this.redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
this.logger.error("hset error:", e);
return false;
}
}
public boolean hset(String key, String item, Object value, long time) {
try {
this.redisTemplate.opsForHash().put(key, item, value);
if (time > 0L) {
expire(key, time);
}
return true;
} catch (Exception e) {
this.logger.error("hset error:", e);
return false;
}
}
public void hdel(String key, Object... item) {
this.redisTemplate.opsForHash().delete(key, item);
}
public boolean hHasKey(String key, String item) {
return this.redisTemplate.opsForHash().hasKey(key, item).booleanValue();
}
public double hincr(String key, String item, double by) {
return this.redisTemplate.opsForHash().increment(key, item, by).doubleValue();
}
public double hdecr(String key, String item, double by) {
return this.redisTemplate.opsForHash().increment(key, item, -by).doubleValue();
}
public Set<Object> sGet(String key) {
try {
return this.redisTemplate.opsForSet().members(key);
} catch (Exception e) {
this.logger.error("sGet error:", e);
return null;
}
}
public boolean sHasKey(String key, Object value) {
try {
return this.redisTemplate.opsForSet().isMember(key, value).booleanValue();
} catch (Exception e) {
this.logger.error("sHasKey error:", e);
return false;
}
}
public long sSet(String key, Object... values) {
try {
return this.redisTemplate.opsForSet().add(key, values).longValue();
} catch (Exception e) {
this.logger.error("sSet error:", e);
return 0L;
}
}
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = this.redisTemplate.opsForSet().add(key, values);
if (time > 0L) {
expire(key, time);
}
return count.longValue();
} catch (Exception e) {
this.logger.error("sSetAndTime error:", e);
return 0L;
}
}
public long sGetSetSize(String key) {
try {
return this.redisTemplate.opsForSet().size(key).longValue();
} catch (Exception e) {
this.logger.error("sGetSetSize error:", e);
return 0L;
}
}
public long setRemove(String key, Object... values) {
try {
Long count = this.redisTemplate.opsForSet().remove(key, values);
return count.longValue();
} catch (Exception e) {
this.logger.error("setRemove error:", e);
return 0L;
}
}
public List<Object> lGet(String key, long start, long end) {
try {
return this.redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
this.logger.error("lGet error:", e);
return null;
}
}
public long lGetListSize(String key) {
try {
return this.redisTemplate.opsForList().size(key).longValue();
} catch (Exception e) {
this.logger.error("lGetListSize error:", e);
return 0L;
}
}
public Object lGetIndex(String key, long index) {
try {
return this.redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
this.logger.error("lGetIndex error:", e);
return null;
}
}
public boolean lSet(String key, Object value) {
try {
this.redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
this.logger.error("lSet error:", e);
return false;
}
}
public boolean lSet(String key, Object value, long time) {
try {
this.redisTemplate.opsForList().rightPush(key, value);
if (time > 0L) {
expire(key, time);
}
return true;
} catch (Exception e) {
this.logger.error("lSet error:", e);
return false;
}
}
public boolean lSet(String key, List<Object> value) {
try {
this.redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
this.logger.error("lSet error:", e);
return false;
}
}
public boolean lSet(String key, List<Object> value, long time) {
try {
this.redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0L) {
expire(key, time);
}
return true;
} catch (Exception e) {
this.logger.error("lSet error:", e);
return false;
}
}
public boolean lUpdateIndex(String key, long index, Object value) {
try {
this.redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
this.logger.error("lUpdateIndex error:", e);
return false;
}
}
public long lRemove(String key, long count, Object value) {
try {
Long remove = this.redisTemplate.opsForList().remove(key, count, value);
return remove.longValue();
} catch (Exception e) {
this.logger.error("lRemove error:", e);
return 0L;
}
}
}
@@ -0,0 +1,5 @@
package cn.cloudwalk.serial.strategy;
public interface ServerIdStrategy {
String getServerId();
}
@@ -0,0 +1,29 @@
package cn.cloudwalk.serial.strategy;
import cn.cloudwalk.serial.autoconfig.serial.CloudwalkSerialProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ServerIdStrategyBeanConfig {
@Bean
public ServerIdStrategy createServerIdStrategy(CloudwalkSerialProperties serialProperties) {
Class<?> beanClassName = ServerIdStrategyEnum.MAC.getClazz();
try {
if (serialProperties != null && serialProperties.getServerIdStrategy() != null) {
if (StringUtils.isNotBlank(serialProperties.getServerIdStrategy().getClassName())) {
beanClassName = Class.forName(serialProperties.getServerIdStrategy().getClassName());
} else if (StringUtils.isNotBlank(serialProperties.getServerIdStrategy().getCode())
|| null != ServerIdStrategyEnum
.getServerIdStrategyEnum(serialProperties.getServerIdStrategy().getCode())) {
beanClassName = Class.forName(ServerIdStrategyEnum
.getServerIdStrategyEnum(serialProperties.getServerIdStrategy().getCode()).getBeanName());
}
}
return (ServerIdStrategy) beanClassName.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,55 @@
package cn.cloudwalk.serial.strategy;
import cn.cloudwalk.serial.strategy.impl.MacServerIdStrategy;
public enum ServerIdStrategyEnum {
MAC("mac", "mac地址策略", MacServerIdStrategy.class, "macServerIdStrategy");
public Class<?> clazz;
private String beanName;
private String name;
private String code;
public String getCode() {
return this.code;
}
public String getName() {
return this.name;
}
ServerIdStrategyEnum(String code, String name, Class<?> clazz, String beanName) {
this.code = code;
this.name = name;
this.clazz = clazz;
this.beanName = beanName;
}
public Class<?> getClazz() {
return this.clazz;
}
public void setClazz(Class<?> clazz) {
this.clazz = clazz;
}
public String getBeanName() {
return this.beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public static ServerIdStrategyEnum getServerIdStrategyEnum(String code) {
for (ServerIdStrategyEnum item : values()) {
if (item.getCode().equals(code)) {
return item;
}
}
return null;
}
}
@@ -0,0 +1,28 @@
package cn.cloudwalk.serial.strategy.impl;
import cn.cloudwalk.cloud.utils.NetworkUtils;
import cn.cloudwalk.serial.strategy.ServerIdStrategy;
import java.net.NetworkInterface;
import java.util.Iterator;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
public class MacServerIdStrategy implements ServerIdStrategy {
private static final String CENTER_LINE = "-";
public String getServerId() {
Set<NetworkInterface> nicSets = NetworkUtils
.getNICs(new NetworkUtils.Filter[] { NetworkUtils.Filter.PHYICAL_ONLY, NetworkUtils.Filter.UP });
Iterator<NetworkInterface> it = nicSets.iterator();
String mac = "";
while (it.hasNext()) {
mac = NetworkUtils.getMacAddress(it.next(), "-");
if (StringUtils.isNotEmpty(mac)) {
break;
}
}
return mac.toUpperCase();
}
}
@@ -0,0 +1,174 @@
package cn.cloudwalk.serial.worker;
import cn.cloudwalk.cloud.serial.UUIDSerial;
import cn.cloudwalk.serial.strategy.ServerIdStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
public class SnowFlakeSerialCode implements UUIDSerial {
private final Logger log = LoggerFactory.getLogger(getClass());
private static final int LOCK_TRY_MAX_TIME = 5;
private static final int THREAD_SLEEP_TIME = 5;
private static final Integer MAX_NODE_ID = Integer.valueOf(31);
private static final Integer MIN_NODE_ID = Integer.valueOf(0);
private static String SNOW_FLAKE_REDIS_KEY = "SNOW_FLAKE_SERIAL_CODE";
private static String SNOW_FLAKE_KEY_LOCK = SNOW_FLAKE_REDIS_KEY + ":LOCK";
private SnowflakeIdWorker idWorker;
private RedisTemplate<String, String> redisTemplate;
public SnowFlakeSerialCode(RedisTemplate<String, String> redisTemplate, ServerIdStrategy serverIdStrategy) {
this.redisTemplate = redisTemplate;
if (redisTemplate == null) {
this.idWorker = new SnowflakeIdWorker(MIN_NODE_ID.intValue(), MIN_NODE_ID.intValue());
} else if (null == this.idWorker) {
ClusterNode tag = getClusterNode(serverIdStrategy.getServerId());
this.idWorker = new SnowflakeIdWorker(tag.getWorkId(), tag.getCenterId());
}
}
public String uuid() {
return Long.toString(this.idWorker.nextId());
}
private ClusterNode getClusterNode(String serverId) {
if (StringUtils.isEmpty(serverId)) {
throw new RuntimeException("无法获取服务器的唯一标志异常,serverId为空!");
}
if (this.redisTemplate.opsForHash().hasKey(SNOW_FLAKE_REDIS_KEY, serverId).booleanValue()) {
Object value = this.redisTemplate.opsForHash().get(SNOW_FLAKE_REDIS_KEY, serverId);
return (ClusterNode) JSONObject.parseObject(value.toString(), ClusterNode.class);
}
return genNewClusterNode(serverId);
}
private ClusterNode getMaxClusterNode(Map<Object, Object> entries) {
ClusterNode maxClusterNode = null;
for (Map.Entry<Object, Object> entry : entries.entrySet()) {
ClusterNode its = (ClusterNode) JSONObject.parseObject(entry.getValue().toString(), ClusterNode.class);
if (maxClusterNode == null) {
maxClusterNode = its;
continue;
}
if (maxClusterNode.getCenterId() < its.getCenterId()) {
maxClusterNode = its;
continue;
}
if (maxClusterNode.getCenterId() == its.getCenterId() && maxClusterNode.getWorkId() < its.getWorkId()) {
maxClusterNode = its;
}
}
return maxClusterNode;
}
private ClusterNode getNextClusterNode(Map<Object, Object> entries) {
ClusterNode max = getMaxClusterNode(entries);
int centerId = max.getCenterId(), workId = max.getWorkId() + 1;
if (workId > MAX_NODE_ID.intValue()) {
if (++centerId > MAX_NODE_ID.intValue()) {
throw new RuntimeException("从redis获取主键生成机器节点数据已饱满.");
}
workId = MIN_NODE_ID.intValue();
}
return new ClusterNode(centerId, workId);
}
private ClusterNode genNewClusterNode(String serverId) {
if (getLock(serverId, Integer.valueOf(5))) {
Map<Object, Object> entries = this.redisTemplate.opsForHash().entries(SNOW_FLAKE_REDIS_KEY);
ClusterNode nextClusterNode = null;
if (entries == null || entries.isEmpty()) {
nextClusterNode = new ClusterNode(MIN_NODE_ID.intValue(), MIN_NODE_ID.intValue());
} else {
nextClusterNode = getNextClusterNode(entries);
}
this.redisTemplate.opsForHash().put(SNOW_FLAKE_REDIS_KEY, serverId, JSON.toJSONString(nextClusterNode));
return nextClusterNode;
}
throw new RuntimeException("从redis获取主键生成机器id和数据中心id繁忙错误!");
}
private boolean getLock(String serverId, Integer maxTimes) {
boolean ret = false;
while (true) {
ret = this.redisTemplate.opsForHash()
.putIfAbsent(SNOW_FLAKE_KEY_LOCK, serverId, Long.toString(System.currentTimeMillis()))
.booleanValue();
if (ret) {
this.redisTemplate.expire(SNOW_FLAKE_KEY_LOCK, 5L, TimeUnit.SECONDS);
return true;
}
try {
TimeUnit.SECONDS.sleep(5L);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
this.log.warn("获取雪花 Redis 锁等待被中断", e);
}
if (!ret) {
Integer integer1 = maxTimes, integer2 = maxTimes = Integer.valueOf(maxTimes.intValue() - 1);
if (integer1.intValue() <= 0)
break;
continue;
}
break;
}
return false;
}
public static class ClusterNode {
private int centerId;
private int workId;
public ClusterNode() {
}
public ClusterNode(int centerId, int workId) {
this.centerId = centerId;
this.workId = workId;
}
public int getCenterId() {
return this.centerId;
}
public int getWorkId() {
return this.workId;
}
public void setCenterId(int centerId) {
this.centerId = centerId;
}
public void setWorkId(int workId) {
this.workId = workId;
}
}
}
@@ -0,0 +1,83 @@
package cn.cloudwalk.serial.worker;
public class SnowflakeIdWorker {
private final long twepoch = 1514736000000L;
private final long workerIdBits = 5L;
private final long datacenterIdBits = 5L;
private final long maxWorkerId = 31L;
private final long maxDatacenterId = 31L;
private final long sequenceBits = 12L;
private final long workerIdShift = 12L;
private final long datacenterIdShift = 17L;
private final long timestampLeftShift = 22L;
private final long sequenceMask = 4095L;
private long workerId;
private long datacenterId;
private long sequence = 0L;
private long lastTimestamp = -1L;
public SnowflakeIdWorker(long workerId, long datacenterId) {
if (workerId > 31L || workerId < 0L) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",
new Object[] { Long.valueOf(31L) }));
}
if (datacenterId > 31L || datacenterId < 0L) {
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0",
new Object[] { Long.valueOf(31L) }));
}
this.workerId = workerId;
this.datacenterId = datacenterId;
}
public synchronized long nextId() {
long timestamp = timeGen();
if (timestamp < this.lastTimestamp) {
throw new RuntimeException(
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds",
new Object[] { Long.valueOf(this.lastTimestamp - timestamp) }));
}
if (this.lastTimestamp == timestamp) {
this.sequence = this.sequence + 1L & 0xFFFL;
if (this.sequence == 0L) {
timestamp = tilNextMillis(this.lastTimestamp);
}
} else {
this.sequence = 0L;
}
this.lastTimestamp = timestamp;
return timestamp - 1514736000000L << 22L | this.datacenterId << 17L | this.workerId << 12L | this.sequence;
}
protected long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
protected long timeGen() {
return System.currentTimeMillis();
}
}
@@ -0,0 +1,3 @@
# Spring Boot 2.1:注册序列号与 Snowflake 相关自动配置(此前缺失导致 AbstractGeneralCode 等 Bean 未创建)
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.cloudwalk.serial.autoconfig.serial.CloudwalkSerialAutoConfiguration