diff --git a/liteflow-rule-plugin/liteflow-rule-redis/pom.xml b/liteflow-rule-plugin/liteflow-rule-redis/pom.xml
new file mode 100644
index 00000000..a5e98349
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-redis/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ liteflow-rule-plugin
+ com.yomahub
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ liteflow-rule-redis
+
+
+
+ com.yomahub
+ liteflow-core
+ ${revision}
+ true
+ provided
+
+
+
+ org.redisson
+ redisson
+ ${redisson.version}
+
+
+
+ cn.hutool
+ hutool-crypto
+ ${hutool-crypto.version}
+
+
+
+
\ No newline at end of file
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/RedisXmlELParser.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/RedisXmlELParser.java
new file mode 100644
index 00000000..547b291c
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/RedisXmlELParser.java
@@ -0,0 +1,109 @@
+package com.yomahub.liteflow.parser.redis;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.bean.copier.CopyOptions;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.text.StrFormatter;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.core.FlowInitHook;
+import com.yomahub.liteflow.parser.el.ClassXmlFlowELParser;
+import com.yomahub.liteflow.parser.redis.exception.RedisException;
+import com.yomahub.liteflow.parser.redis.mode.polling.RedisParserPollingMode;
+import com.yomahub.liteflow.parser.redis.mode.subscribe.RedisParserSubscribeMode;
+import com.yomahub.liteflow.parser.redis.mode.RedisParserHelper;
+import com.yomahub.liteflow.parser.redis.mode.RedisParserMode;
+import com.yomahub.liteflow.parser.redis.vo.RedisParserVO;
+import com.yomahub.liteflow.property.LiteflowConfig;
+import com.yomahub.liteflow.property.LiteflowConfigGetter;
+import com.yomahub.liteflow.util.JsonUtil;
+
+import java.util.Objects;
+
+/**
+ * Redis解析器实现,只支持EL形式的XML,不支持其他的形式
+ *
+ * @author hxinyu
+ * @since 2.11.0
+ */
+
+public class RedisXmlELParser extends ClassXmlFlowELParser {
+
+ private final RedisParserHelper redisParserHelper;
+
+ private static final String ERROR_COMMON_MSG = "ruleSourceExtData or map is empty";
+
+ private static final String ERROR_MSG_PATTERN = "ruleSourceExtData {} is blank";
+
+ public RedisXmlELParser() {
+ LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+
+ try {
+ RedisParserVO redisParserVO = null;
+ if (MapUtil.isNotEmpty((liteflowConfig.getRuleSourceExtDataMap()))) {
+ redisParserVO = BeanUtil.toBean(liteflowConfig.getRuleSourceExtDataMap(),
+ RedisParserVO.class, CopyOptions.create());
+ }
+ else if (StrUtil.isNotBlank(liteflowConfig.getRuleSourceExtData())) {
+ redisParserVO = JsonUtil.parseObject(liteflowConfig.getRuleSourceExtData(), RedisParserVO.class);
+ }
+ if (Objects.isNull(redisParserVO)) {
+ throw new RedisException(ERROR_COMMON_MSG);
+ }
+
+ //检查配置文件
+ checkParserVO(redisParserVO);
+
+ //选择订阅机制 or 轮询机制
+ RedisParserMode mode = redisParserVO.getMode();
+ switch (mode) {
+ case SUB:
+ case SUBSCRIBE:
+ redisParserHelper = new RedisParserSubscribeMode(redisParserVO);
+ break;
+ case POLL:
+ default:
+ redisParserHelper = new RedisParserPollingMode(redisParserVO);
+ break;
+ }
+
+ }
+ catch (RedisException redisException) {
+ throw redisException;
+ }
+ catch (Exception e) {
+ throw new RedisException(e.getMessage());
+ }
+ }
+
+ @Override
+ public String parseCustom() {
+ try {
+ String content = redisParserHelper.getContent();
+ FlowInitHook.addHook(() -> {
+ redisParserHelper.listenRedis();
+ return true;
+ });
+ return content;
+
+ }
+ catch (Exception e) {
+ throw new RedisException(e.getMessage());
+ }
+ }
+
+ private void checkParserVO(RedisParserVO redisParserVO) {
+ if (StrUtil.isBlank(redisParserVO.getHost())) {
+ throw new RedisException(StrFormatter.format(ERROR_MSG_PATTERN, "host"));
+ }
+ if (ObjectUtil.isNull(redisParserVO.getPort())) {
+ throw new RedisException(StrFormatter.format(ERROR_MSG_PATTERN, "port"));
+ }
+ if (ObjectUtil.isNull(redisParserVO.getChainDataBase())) {
+ throw new RedisException(StrFormatter.format(ERROR_MSG_PATTERN, "chainDataBase"));
+ }
+ if (StrUtil.isBlank(redisParserVO.getChainKey())) {
+ throw new RedisException(StrFormatter.format(ERROR_MSG_PATTERN, "chainKey"));
+ }
+ }
+}
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/exception/RedisException.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/exception/RedisException.java
new file mode 100644
index 00000000..1b6ee435
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/exception/RedisException.java
@@ -0,0 +1,23 @@
+package com.yomahub.liteflow.parser.redis.exception;
+
+/**
+ * Redis解析异常
+ *
+ * @author hxinyu
+ * @since 2.11.0
+ */
+
+public class RedisException extends RuntimeException{
+
+ private String message;
+
+ public RedisException(String message) {
+ super();
+ this.message = message;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RClient.java b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RClient.java
new file mode 100644
index 00000000..cfa4a1bf
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-redis/src/main/java/com/yomahub/liteflow/parser/redis/mode/RClient.java
@@ -0,0 +1,109 @@
+package com.yomahub.liteflow.parser.redis.mode;
+
+import cn.hutool.core.collection.CollectionUtil;
+import org.redisson.api.RMap;
+import org.redisson.api.RMapCache;
+import org.redisson.api.RScript;
+import org.redisson.api.RedissonClient;
+import org.redisson.api.map.event.MapEntryListener;
+import org.redisson.client.codec.StringCodec;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Redisson 客户端封装类.
+ *
+ * @author hxinyu
+ * @since 2.11.0
+ */
+public class RClient {
+
+ private final RedissonClient redissonClient;
+
+ private Map map = new HashMap<>();
+
+ public RClient(RedissonClient redissonClient) {
+ this.redissonClient = redissonClient;
+ }
+
+
+ /**
+ * get hashmap of the key
+ *
+ * @param key hash name
+ * @return hashmap
+ */
+ public Map getMap(String key) {
+ RMapCache mapCache = redissonClient.getMapCache(key);
+ Set mapFieldSet = mapCache.keySet();
+ if (CollectionUtil.isEmpty(mapFieldSet)) {
+ return map;
+ }
+ for (String field : mapFieldSet) {
+ String value = mapCache.get(field);
+ map.put(field, value);
+ }
+ return map;
+ }
+
+
+ /**
+ * add listener of the key
+ *
+ * @param key hash name
+ * @param listener listener
+ * @return listener id
+ */
+ public int addListener(String key, MapEntryListener listener) {
+ RMapCache