diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisMode.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisMode.java
new file mode 100644
index 000000000..ce5610428
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisMode.java
@@ -0,0 +1,27 @@
+package com.yomahub.liteflow.parser.redis.mode;
+
+/**
+ * 用于定义Redis模式的枚举类
+ *
+ * single单点模式, sentinel哨兵模式
+ * 不支持集群模式配置
+ *
+ * @author hxinyu
+ * @since 2.11.0
+ */
+public enum RedisMode {
+
+ SINGLE("single"),
+
+ SENTINEL("sentinel");
+
+ private String mode;
+
+ RedisMode(String mode) {
+ this.mode = mode;
+ }
+
+ public String getMode() {
+ return mode;
+ }
+}
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserHelper.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserHelper.java
index 356e86a5d..eb60d2cdd 100644
--- a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserHelper.java
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserHelper.java
@@ -10,6 +10,7 @@ import com.yomahub.liteflow.log.LFLog;
import com.yomahub.liteflow.log.LFLoggerManager;
import com.yomahub.liteflow.parser.redis.vo.RedisParserVO;
import org.redisson.config.Config;
+import org.redisson.config.SentinelServersConfig;
import java.util.List;
@@ -24,7 +25,9 @@ public interface RedisParserHelper {
LFLog LOG = LFLoggerManager.getLogger(RedisParserHelper.class);
- String REDIS_URL_PATTERN = "redis://{}:{}";
+ String SINGLE_REDIS_URL_PATTERN = "redis://{}:{}";
+
+ String SENTINEL_REDIS_URL_PATTERN = "redis://{}";
String CHAIN_XML_PATTERN = "{}";
@@ -42,16 +45,23 @@ public interface RedisParserHelper {
/**
- * 获取Redisson客户端的Config配置通用方法
+ * 获取Redisson客户端的Config配置通用方法(单点模式)
* @param redisParserVO redisParserVO
- * @param dataBase redisson连接的数据库号
+ * @param dataBase redis连接的数据库号
* @return redisson config
*/
- default Config getRedissonConfig(RedisParserVO redisParserVO, Integer dataBase) {
+ default Config getSingleRedissonConfig(RedisParserVO redisParserVO, Integer dataBase) {
Config config = new Config();
- String redisAddress = StrFormatter.format(REDIS_URL_PATTERN, redisParserVO.getHost(), redisParserVO.getPort());
+ String redisAddress = StrFormatter.format(SINGLE_REDIS_URL_PATTERN, redisParserVO.getHost(), redisParserVO.getPort());
+ //如果配置了用户名和密码
+ if (StrUtil.isNotBlank(redisParserVO.getUsername()) && StrUtil.isNotBlank(redisParserVO.getPassword())) {
+ config.useSingleServer().setAddress(redisAddress)
+ .setUsername(redisParserVO.getUsername())
+ .setPassword(redisParserVO.getPassword())
+ .setDatabase(dataBase);
+ }
//如果配置了密码
- if (StrUtil.isNotBlank(redisParserVO.getPassword())) {
+ else if (StrUtil.isNotBlank(redisParserVO.getPassword())) {
config.useSingleServer().setAddress(redisAddress)
.setPassword(redisParserVO.getPassword())
.setDatabase(dataBase);
@@ -64,6 +74,37 @@ public interface RedisParserHelper {
return config;
}
+ /**
+ * 获取Redisson客户端的Config配置通用方法(哨兵模式)
+ * @param redisParserVO redisParserVO
+ * @param dataBase redis连接的数据库号
+ * @return redisson Config
+ */
+ default Config getSentinelRedissonConfig(RedisParserVO redisParserVO, Integer dataBase) {
+ Config config = new Config();
+ SentinelServersConfig sentinelConfig = config.useSentinelServers()
+ .setMasterName(redisParserVO.getMasterName());
+ redisParserVO.getSentinelAddress().forEach(address -> {
+ sentinelConfig.addSentinelAddress(StrFormatter.format(SENTINEL_REDIS_URL_PATTERN, address));
+ });
+ //如果配置了用户名和密码
+ if(StrUtil.isNotBlank(redisParserVO.getUsername()) && StrUtil.isNotBlank(redisParserVO.getPassword())) {
+ sentinelConfig.setUsername(redisParserVO.getUsername())
+ .setPassword(redisParserVO.getPassword())
+ .setDatabase(dataBase);
+ }
+ //如果配置了密码
+ else if(StrUtil.isNotBlank(redisParserVO.getPassword())) {
+ sentinelConfig.setPassword(redisParserVO.getPassword())
+ .setDatabase(dataBase);
+ }
+ //没有配置密码
+ else {
+ sentinelConfig.setDatabase(dataBase);
+ }
+ return config;
+ }
+
/**
* script节点的修改/添加
*
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserMode.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserMode.java
index 13c4b8753..258229c61 100644
--- a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserMode.java
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RedisParserMode.java
@@ -1,8 +1,9 @@
package com.yomahub.liteflow.parser.redis.mode;
/**
- * 用于定义redis规则存储和监听方式的枚举类
+ * 用于定义Redis规则存储和监听方式的枚举类
*
+ * poll轮询拉取模式, sub监听模式
* @author hxinyu
* @since 2.11.0
*/
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/polling/RedisParserPollingMode.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/polling/RedisParserPollingMode.java
index ae4d2ee38..b9c3b2ea7 100644
--- a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/polling/RedisParserPollingMode.java
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/polling/RedisParserPollingMode.java
@@ -8,6 +8,7 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.yomahub.liteflow.parser.redis.exception.RedisException;
import com.yomahub.liteflow.parser.redis.mode.RClient;
+import com.yomahub.liteflow.parser.redis.mode.RedisMode;
import com.yomahub.liteflow.parser.redis.mode.RedisParserHelper;
import com.yomahub.liteflow.parser.redis.vo.RedisParserVO;
import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
@@ -75,12 +76,28 @@ public class RedisParserPollingMode implements RedisParserHelper {
catch (Exception ignored) {
}
if (ObjectUtil.isNull(chainClient)) {
- Config config = getRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
- this.chainClient = new RClient(Redisson.create(config));
- //如果有脚本数据
- if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
- config = getRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
- this.scriptClient = new RClient(Redisson.create(config));
+ RedisMode redisMode = redisParserVO.getRedisMode();
+ Config config;
+ //Redis单点模式
+ if (redisMode.equals(RedisMode.SINGLE)){
+ config = getSingleRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
+ this.chainClient = new RClient(Redisson.create(config));
+ //如果有脚本数据
+ if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
+ config = getSingleRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
+ this.scriptClient = new RClient(Redisson.create(config));
+ }
+ }
+
+ //Redis哨兵模式
+ else if (redisMode.equals(RedisMode.SENTINEL)) {
+ config = getSentinelRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
+ this.chainClient = new RClient(Redisson.create(config));
+ //如果有脚本数据
+ if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
+ config = getSentinelRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
+ this.scriptClient = new RClient(Redisson.create(config));
+ }
}
}
//创建定时任务线程池
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/subscribe/RedisParserSubscribeMode.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/subscribe/RedisParserSubscribeMode.java
index 67c9697f2..b115baec5 100644
--- a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/subscribe/RedisParserSubscribeMode.java
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/subscribe/RedisParserSubscribeMode.java
@@ -8,6 +8,7 @@ import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
import com.yomahub.liteflow.flow.FlowBus;
import com.yomahub.liteflow.parser.redis.exception.RedisException;
import com.yomahub.liteflow.parser.redis.mode.RClient;
+import com.yomahub.liteflow.parser.redis.mode.RedisMode;
import com.yomahub.liteflow.parser.redis.mode.RedisParserHelper;
import com.yomahub.liteflow.parser.redis.vo.RedisParserVO;
import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
@@ -48,12 +49,28 @@ public class RedisParserSubscribeMode implements RedisParserHelper {
catch (Exception ignored) {
}
if (ObjectUtil.isNull(chainClient)) {
- Config config = getRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
- this.chainClient = new RClient(Redisson.create(config));
- //如果有脚本数据
- if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
- config = getRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
- this.scriptClient = new RClient(Redisson.create(config));
+ RedisMode redisMode = redisParserVO.getRedisMode();
+ Config config;
+ //Redis单点模式
+ if (redisMode.equals(RedisMode.SINGLE)){
+ config = getSingleRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
+ this.chainClient = new RClient(Redisson.create(config));
+ //如果有脚本数据
+ if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
+ config = getSingleRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
+ this.scriptClient = new RClient(Redisson.create(config));
+ }
+ }
+
+ //Redis哨兵模式
+ else if (redisMode.equals(RedisMode.SENTINEL)) {
+ config = getSentinelRedissonConfig(redisParserVO, redisParserVO.getChainDataBase());
+ this.chainClient = new RClient(Redisson.create(config));
+ //如果有脚本数据
+ if (ObjectUtil.isNotNull(redisParserVO.getScriptDataBase())) {
+ config = getSentinelRedissonConfig(redisParserVO, redisParserVO.getScriptDataBase());
+ this.scriptClient = new RClient(Redisson.create(config));
+ }
}
}
}
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/vo/RedisParserVO.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/vo/RedisParserVO.java
index 9ec2026f8..7aeaecd70 100644
--- a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/vo/RedisParserVO.java
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/vo/RedisParserVO.java
@@ -1,9 +1,12 @@
package com.yomahub.liteflow.parser.redis.vo;
+import com.yomahub.liteflow.parser.redis.mode.RedisMode;
import com.yomahub.liteflow.parser.redis.mode.RedisParserMode;
+import java.util.List;
+
/**
- * 用于解析RuleSourceExtData的vo类,用于Redis模式中
+ * 用于解析RuleSourceExtData的vo类, 用于Redis模式中
*
* @author hxinyu
* @since 2.11.0
@@ -11,12 +14,24 @@ import com.yomahub.liteflow.parser.redis.mode.RedisParserMode;
public class RedisParserVO {
- /*连接地址*/
+ /*Redis配置模式 单点/哨兵, 默认为单点模式*/
+ private RedisMode redisMode = RedisMode.SINGLE;
+
+ /*单点模式 连接地址*/
private String host;
- /*端口号*/
+ /*单点模式 端口号*/
private Integer port;
+ /*哨兵模式 主节点名*/
+ private String masterName;
+
+ /*哨兵模式 哨兵节点连接地址 ip:port, 可配置多个*/
+ private List sentinelAddress;
+
+ /*用户名 需要Redis 6.0及以上*/
+ private String username;
+
/*密码*/
private String password;
@@ -41,6 +56,21 @@ public class RedisParserVO {
/*脚本配置的键名 若没有脚本数据可不配置*/
private String scriptKey;
+ public void setRedisMode(String redisMode) {
+ redisMode = redisMode.toUpperCase();
+ try{
+ RedisMode m = RedisMode.valueOf(redisMode);
+ this.redisMode = m;
+ }
+ catch (Exception ignored) {
+ //转换出错默认为单点模式
+ }
+ }
+
+ public RedisMode getRedisMode() {
+ return redisMode;
+ }
+
public String getHost() {
return host;
}
@@ -57,6 +87,30 @@ public class RedisParserVO {
this.port = port;
}
+ public String getMasterName() {
+ return masterName;
+ }
+
+ public void setMasterName(String masterName) {
+ this.masterName = masterName;
+ }
+
+ public List getSentinelAddress() {
+ return sentinelAddress;
+ }
+
+ public void setSentinelAddress(List sentinelAddress) {
+ this.sentinelAddress = sentinelAddress;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
public String getPassword() {
return password;
}
@@ -127,4 +181,24 @@ public class RedisParserVO {
public void setScriptKey(String scriptKey) {
this.scriptKey = scriptKey;
}
+
+ @Override
+ public String toString() {
+ return "RedisParserVO{" +
+ "redisMode=" + redisMode +
+ ", host='" + host + '\'' +
+ ", port=" + port +
+ ", masterName=" + masterName +
+ ", sentinelAddress=" + sentinelAddress +
+ ", username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ ", mode=" + mode +
+ ", pollingInterval=" + pollingInterval +
+ ", pollingStartTime=" + pollingStartTime +
+ ", chainDataBase=" + chainDataBase +
+ ", chainKey='" + chainKey + '\'' +
+ ", scriptDataBase=" + scriptDataBase +
+ ", scriptKey='" + scriptKey + '\'' +
+ '}';
+ }
}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisSubscribeTestCondition.java b/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisSubscribeTestCondition.java
deleted file mode 100644
index 724e8df75..000000000
--- a/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisSubscribeTestCondition.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.yomahub.liteflow.test.redis;
-
-import cn.hutool.core.util.StrUtil;
-import org.redisson.Redisson;
-import org.redisson.api.RedissonClient;
-import org.redisson.api.redisnode.RedisNodes;
-import org.redisson.api.redisnode.RedisSingle;
-import org.redisson.config.Config;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * 判断本地6379端口是否启动了Redis
- */
-public class RedisSubscribeTestCondition {
-
- /**
- * @return true为本地未启动Redis
- */
- public static boolean notStartRedis() {
- try{
- Config config = new Config();
- config.useSingleServer().setAddress("redis://127.0.0.1:6379");
- RedissonClient redissonClient = Redisson.create(config);
- RedisSingle redisNode = redissonClient.getRedisNodes(RedisNodes.SINGLE);
- return !redisNode.pingAll(15000, TimeUnit.MICROSECONDS);
- } catch (Exception e) {
- return true;
- }
- }
-}