mirror of
https://github.com/hpd840321/starRiverProperty.git
synced 2026-06-09 08:20:31 +08:00
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:
@@ -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>
|
||||
+57
@@ -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;
|
||||
}
|
||||
}
|
||||
+54
@@ -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;
|
||||
}
|
||||
}
|
||||
+22
@@ -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);
|
||||
}
|
||||
}
|
||||
+22
@@ -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;
|
||||
}
|
||||
}
|
||||
+26
@@ -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);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package cn.cloudwalk.serial.code;
|
||||
|
||||
public interface GeneralSerial {
|
||||
Integer generalSerial();
|
||||
}
|
||||
+35
@@ -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();
|
||||
}
|
||||
}
|
||||
+24
@@ -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;
|
||||
}
|
||||
}
|
||||
+30
@@ -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);
|
||||
}
|
||||
}
|
||||
+44
@@ -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);
|
||||
}
|
||||
}
|
||||
+326
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package cn.cloudwalk.serial.strategy;
|
||||
|
||||
public interface ServerIdStrategy {
|
||||
String getServerId();
|
||||
}
|
||||
+29
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -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;
|
||||
}
|
||||
}
|
||||
+28
@@ -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();
|
||||
}
|
||||
}
|
||||
+174
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+83
@@ -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();
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# Spring Boot 2.1:注册序列号与 Snowflake 相关自动配置(此前缺失导致 AbstractGeneralCode 等 Bean 未创建)
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
cn.cloudwalk.serial.autoconfig.serial.CloudwalkSerialAutoConfiguration
|
||||
Reference in New Issue
Block a user