add sentinel mode

This commit is contained in:
houxinyu
2023-08-20 02:11:28 +08:00
parent d3db183903
commit 325cec7113
7 changed files with 199 additions and 53 deletions

View File

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

View File

@@ -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节点的修改/添加
*

View File

@@ -1,8 +1,9 @@
package com.yomahub.liteflow.parser.redis.mode;
/**
* 用于定义redis规则存储和监听方式的枚举类
* 用于定义Redis规则存储和监听方式的枚举类
*
* poll轮询拉取模式, sub监听模式
* @author hxinyu
* @since 2.11.0
*/

View File

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

View File

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

View File

@@ -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 + '\'' +
'}';
}
}

View File

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