houxinyu 1 anno fa
parent
commit
325cec7113

+ 27 - 0
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;
+    }
+}

+ 47 - 6
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 = "<chain name=\"{}\">{}</chain>";
 
@@ -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节点的修改/添加
      *

+ 2 - 1
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
  */

+ 23 - 6
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));
+                    }
                 }
             }
             //创建定时任务线程池

+ 23 - 6
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));
+                    }
                 }
             }
         }

+ 77 - 3
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<String> 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<String> getSentinelAddress() {
+        return sentinelAddress;
+    }
+
+    public void setSentinelAddress(List<String> 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 + '\'' +
+                '}';
+    }
 }

+ 0 - 31
liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/java/com/yomahub/liteflow/test/redis/RedisSubscribeTestCondition.java

@@ -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;
-        }
-    }
-}