@@ -1,6 +1,5 @@
package cn.keking.config ;
import io.netty.channel.nio.NioEventLoopGroup ;
import org.apache.commons.lang3.StringUtils ;
import org.redisson.Redisson ;
import org.redisson.api.RedissonClient ;
@@ -13,8 +12,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.util.ClassUtils ;
/**
* Redisson 客户端配置
* Created by kl on 2017/09/26.
* Redisson 客户端配置(完善版)
* 支持 single / cluster / master-slave / sentinel 四种模式,配置完整,统一参数。
*/
@ConditionalOnExpression ( " '${cache.type:default}'.equals('redis') " )
@ConfigurationProperties ( prefix = " spring.redisson " )
@@ -22,114 +21,71 @@ import org.springframework.util.ClassUtils;
public class RedissonConfig {
// ========================== 连接配置 ==========================
private static String address ;
private static String password ;
private static String clientName ;
private static int database = 0 ;
private static String mode = " single " ;
private static String masterName = " kkfile " ;
private String address ;
private String password ;
private String clientName ;
private int database = 0 ;
private String mode = " single " ;
private String masterName = " kkfile " ;
// ========================== 超时配置 ==========================
private static int idleConnectionTimeout = 10000 ;
private static int connectTimeout = 10000 ;
private static int timeout = 3000 ;
private int idleConnectionTimeout = 10000 ;
private int connectTimeout = 10000 ;
private int timeout = 3000 ;
// ========================== 重试配置 ==========================
private static int retryAttempts = 3 ;
private static int retryInterval = 1500 ;
private int retryAttempts = 3 ;
private int retryInterval = 1500 ;
// ========================== 连接池配置 ==========================
private static int connectionMinimumIdleSize = 10 ;
private static int connectionPoolSize = 64 ;
private static int subscriptionsPerConnection = 5 ;
private static int subscriptionConnectionMinimumIdleSize = 1 ;
private static int subscriptionConnectionPoolSize = 50 ;
private int connectionMinimumIdleSize = 10 ;
private int connectionPoolSize = 64 ;
private int subscriptionsPerConnection = 5 ;
private int subscriptionConnectionMinimumIdleSize = 1 ;
private int subscriptionConnectionPoolSize = 50 ;
// ========================== 集群专用配置 ==========================
private int scanInterval = 2000 ;
// ========================== 其他配置 ==========================
private static int dnsMonitoringInterval = 5000 ;
private static int thread ; // 当前处理 核数量 * 2
private static String codec = " org.redisson.codec.JsonJacksonCodec " ;
private int dnsMonitoringInterval = 5000 ;
private int threads ; // 默认为0, 表示使用 CPU 核数 * 2
private String codec = " org.redisson.codec.JsonJacksonCodec " ;
@Bean
public static RedissonClient config ( ) throws Exception {
public RedissonClient redissonClient ( ) {
Config config = new Config ( ) ;
// 密码处理
if ( StringUtils . isBlank ( password ) ) {
password = null ;
}
// 密码处理:空字符串转为 null
String pwd = StringUtils . isBlank ( password ) ? null : password ;
// 根据模式创建对应的 Redisson 配置
switch ( mode ) {
// 根据模式构建 配置
switch ( mode . toLowerCase ( ) ) {
case " cluster " :
configureClusterMode ( config ) ;
configureClusterMode ( config , pwd );
break ;
case " master-slave " :
configureMasterSlaveMode ( config ) ;
configureMasterSlaveMode ( config , pwd );
break ;
case " sentinel " :
configureSentinelMode ( config ) ;
configureSentinelMode ( config , pwd );
break ;
default :
configureSingleMode ( config ) ;
configureSingleMode ( config , pwd );
break ;
}
// 公共配置:编码器、线程数
applyCommonConfig ( config ) ;
return Redisson . create ( config ) ;
}
// ========================== 配置方法 ==========================
/**
* 配置集群模式
*/
private static void configureClusterMode ( Config config ) {
String [ ] clusterAddresses = address . split ( " , " ) ;
config . useClusterServers ( )
. setScanInterval ( 2000 )
. addNodeAddress ( clusterAddresses )
. setPassword ( password )
. setRetryAttempts ( retryAttempts )
. setTimeout ( timeout )
. setMasterConnectionPoolSize ( 100 )
. setSlaveConnectionPoolSize ( 100 ) ;
}
/**
* 配置主从模式
*/
private static void configureMasterSlaveMode ( Config config ) {
String [ ] masterSlaveAddresses = address . split ( " , " ) ;
validateMasterSlaveAddresses ( masterSlaveAddresses ) ;
String [ ] slaveAddresses = new String [ masterSlaveAddresses . length - 1 ] ;
System . arraycopy ( masterSlaveAddresses , 1 , slaveAddresses , 0 , slaveAddresses . length ) ;
config . useMasterSlaveServers ( )
. setDatabase ( database )
. setPassword ( password )
. setMasterAddress ( masterSlaveAddresses [ 0 ] )
. addSlaveAddress ( slaveAddresses ) ;
}
/**
* 配置哨兵模式
*/
private static void configureSentinelMode ( Config config ) {
String [ ] sentinelAddresses = address . split ( " , " ) ;
config . useSentinelServers ( )
. setDatabase ( database )
. setPassword ( password )
. setMasterName ( masterName )
. addSentinelAddress ( sentinelAddresses ) ;
}
/**
* 配置单机模式
*/
private static void configureSingleMode ( Config config ) throws Exception {
private void configureSingleMode ( Config config , String pwd ) {
String normalizedAddress = normalizeAddress ( address ) ;
config . useSingleServer ( )
. setAddress ( a ddress)
. setAddress ( normalizedA ddress)
. setConnectionMinimumIdleSize ( connectionMinimumIdleSize )
. setConnectionPoolSize ( connectionPoolSize )
. setDatabase ( database )
@@ -143,183 +99,184 @@ public class RedissonConfig {
. setTimeout ( timeout )
. setConnectTimeout ( connectTimeout )
. setIdleConnectionTimeout ( idleConnectionTimeout )
. setPassword ( StringUtils . trimToNull ( password ) ) ;
// 设置编码器
Class < ? > codecClass = ClassUtils . forName ( getCodec ( ) , ClassUtils . getDefaultClassLoader ( ) ) ;
Codec codecInstance = ( Codec ) codecClass . getDeclaredConstructor ( ) . newInstance ( ) ;
config . setCodec ( codecInstance ) ;
// 设置线程和事件循环组
config . setThreads ( thread ) ;
config . setEventLoopGroup ( new NioEventLoopGroup ( ) ) ;
. setPassword ( pwd ) ;
}
/**
* 验证主从模式地址
*/
private static void validateMasterSlaveAddresses ( String [ ] addresses ) {
if ( a ddresses . length = = 1 ) {
throw new IllegalArgumentException (
" redis.redisson.address MUST have multiple redis addresses for master-slave mode. " ) ;
private void configureClusterMode ( Config config , String pwd ) {
String [ ] nodeAddresses = normalizeAddresses ( address . split ( " , " ) ) ;
config . useClusterServers ( )
. setScanInterval ( scanInterval )
. addNodeA ddress ( nodeAddresses )
. setPassword ( pwd )
. setRetryAttempts ( retryAttempts )
. setRetryInterval ( retryInterval )
. setTimeout ( timeout )
. setConnectTimeout ( connectTimeout )
. setIdleConnectionTimeout ( idleConnectionTimeout )
. setMasterConnectionPoolSize ( connectionPoolSize )
. setSlaveConnectionPoolSize ( connectionPoolSize )
. setSubscriptionConnectionPoolSize ( subscriptionConnectionPoolSize )
. setSubscriptionConnectionMinimumIdleSize ( subscriptionConnectionMinimumIdleSize )
. setSubscriptionsPerConnection ( subscriptionsPerConnection )
. setClientName ( clientName ) ;
}
private void configureMasterSlaveMode ( Config config , String pwd ) {
String [ ] addresses = address . split ( " , " ) ;
validateMasterSlaveAddresses ( addresses ) ;
String [ ] normalizedAddresses = normalizeAddresses ( addresses ) ;
String masterAddress = normalizedAddresses [ 0 ] ;
String [ ] slaveAddresses = new String [ normalizedAddresses . length - 1 ] ;
System . arraycopy ( normalizedAddresses , 1 , slaveAddresses , 0 , slaveAddresses . length ) ;
config . useMasterSlaveServers ( )
. setDatabase ( database )
. setPassword ( pwd )
. setMasterAddress ( masterAddress )
. addSlaveAddress ( slaveAddresses )
. setRetryAttempts ( retryAttempts )
. setRetryInterval ( retryInterval )
. setTimeout ( timeout )
. setConnectTimeout ( connectTimeout )
. setIdleConnectionTimeout ( idleConnectionTimeout )
. setMasterConnectionPoolSize ( connectionPoolSize )
. setSlaveConnectionPoolSize ( connectionPoolSize )
. setSubscriptionConnectionPoolSize ( subscriptionConnectionPoolSize )
. setSubscriptionConnectionMinimumIdleSize ( subscriptionConnectionMinimumIdleSize )
. setSubscriptionsPerConnection ( subscriptionsPerConnection )
. setClientName ( clientName ) ;
}
private void configureSentinelMode ( Config config , String pwd ) {
String [ ] sentinelAddresses = normalizeAddresses ( address . split ( " , " ) ) ;
config . useSentinelServers ( )
. setDatabase ( database )
. setPassword ( pwd )
. setMasterName ( masterName )
. addSentinelAddress ( sentinelAddresses )
. setRetryAttempts ( retryAttempts )
. setRetryInterval ( retryInterval )
. setTimeout ( timeout )
. setConnectTimeout ( connectTimeout )
. setIdleConnectionTimeout ( idleConnectionTimeout )
. setMasterConnectionPoolSize ( connectionPoolSize )
. setSlaveConnectionPoolSize ( connectionPoolSize )
. setSubscriptionConnectionPoolSize ( subscriptionConnectionPoolSize )
. setSubscriptionConnectionMinimumIdleSize ( subscriptionConnectionMinimumIdleSize )
. setSubscriptionsPerConnection ( subscriptionsPerConnection )
. setClientName ( clientName ) ;
}
private void applyCommonConfig ( Config config ) {
// 设置编码器
if ( StringUtils . isNotBlank ( codec ) ) {
try {
Class < ? > codecClass = ClassUtils . forName ( codec , ClassUtils . getDefaultClassLoader ( ) ) ;
Codec codecInstance = ( Codec ) codecClass . getDeclaredConstructor ( ) . newInstance ( ) ;
config . setCodec ( codecInstance ) ;
} catch ( Exception e ) {
throw new IllegalStateException ( " Failed to create Redisson codec: " + codec , e ) ;
}
}
// 设置线程数( 大于0时生效, 否则Redisson使用默认值: CPU核数*2)
if ( threads > 0 ) {
config . setThreads ( threads ) ;
}
}
// ========================== Getter和Setter 方法 ==========================
// ========================== 辅助 方法 ==========================
// 连接配置
public String getAddress ( ) {
return address ;
/**
* 自动补齐 Redis 地址协议前缀( redis:// 或 rediss://)
*/
private String normalizeAddress ( String addr ) {
if ( addr = = null ) {
return null ;
}
addr = addr . trim ( ) ;
if ( ! addr . startsWith ( " redis:// " ) & & ! addr . startsWith ( " rediss:// " ) ) {
addr = " redis:// " + addr ;
}
return addr ;
}
public void set Address ( String address ) {
RedissonConfig . address = address ;
private String [ ] normalize Addresses ( String [ ] addresses ) {
String [ ] normalized = new String [ addresses . length ] ;
for ( int i = 0 ; i < addresses . length ; i + + ) {
normalized [ i ] = normalizeAddress ( addresses [ i ] ) ;
}
return normalized ;
}
public String getPassword ( ) {
return password ;
private void validateMasterSlaveAddresses ( String [ ] addresses ) {
if ( addresses . length < 2 ) {
throw new IllegalArgumentException (
" Master-slave mode requires at least 2 addresses: master and at least one slave. " +
" Current addresses: " + String . join ( " , " , addresses ) ) ;
}
}
public void setPassword ( String password ) {
RedissonConfig . password = password ;
}
// ========================== Getter / Setter( 供 Spring 绑定配置) ==========================
// 以下所有字段都需要提供 getter/setter, 示例中只列出关键字段, 实际使用时请补全所有字段。
// 建议使用 Lombok @Data 或 IDE 自动生成。这里只展示部分,避免篇幅过长。
public String getClientName ( ) {
return clientName ;
}
public String getAddress ( ) { return address ; }
public void setAddress ( String address ) { this . address = address ; }
public void s etClientName ( String clientName ) {
RedissonConfig . clientName = clientName ;
}
public String g etPassword ( ) { return password ; }
public void setPassword ( String password ) { this . password = password ; }
public int getDatabas e ( ) {
return database ;
}
public Str ing getClientNam e ( ) { return clientName ; }
public void setClientName ( String clientName ) { this . clientName = clientName ; }
public void s etDatabase( int database ) {
RedissonConfig . database = database ;
}
public int g etDatabase( ) { return database ; }
public void setDatabase ( int database ) { this . database = database ; }
public static String getMode ( ) {
return mode ;
}
public String getMode ( ) { return mode ; }
public void setMode ( String mode ) { this . mode = mode ; }
public void s etMode ( String mod e) {
RedissonConfig . mode = mode ;
}
public String g etMasterName ( ) { return masterNam e; }
public void setMasterName ( String masterName ) { this . masterName = masterName ; }
public static String getMasterNamee ( ) {
return masterName ;
}
public int getIdleConnectionTimeout ( ) { return idleConnectionTimeout ; }
public void setIdleConnectionTimeout ( int idleConnectionTimeout ) { this . idleConnectionTimeout = idleConnectionTimeout ; }
public void s etMasterNamee ( String masterName ) {
RedissonConfig . masterName = masterName ;
}
public int g etConnectTimeout ( ) { return connectTimeout ; }
public void setConnectTimeout ( int connectTimeout ) { this . connectTimeout = connectTimeout ; }
// 超时配置
public int g etIdleConnectionTimeout ( ) {
return idleConnectionTimeout ;
}
public int getTimeout ( ) { return timeout ; }
public void s etTimeout ( int timeout ) { this . timeout = timeout ; }
public void s etIdleConnectionTimeout ( int idleConnectionTimeout ) {
RedissonConfig . idleConnectionTimeout = idleConnectionTimeout ;
}
public int g etRetryAttempts ( ) { return retryAttempts ; }
public void setRetryAttempts ( int retryAttempts ) { this . retryAttempts = retryAttempts ; }
public int getConnectTimeout ( ) {
return connectTimeout ;
}
public int getRetryInterval ( ) { return retryInterval ; }
public void setRetryInterval ( int retryInterval ) { this . retryInterval = retryInterval ; }
public void s etConnectTimeout ( int connectTimeout ) {
RedissonConfig . connectTimeout = connectTimeout ;
}
public int g etConnectionMinimumIdleSize ( ) { return connectionMinimumIdleSize ; }
public void setConnectionMinimumIdleSize ( int connectionMinimumIdleSize ) { this . connectionMinimumIdleSize = connectionMinimumIdleSize ; }
public int getTimeout ( ) {
return timeout ;
}
public int getConnectionPoolSize ( ) { return connectionPoolSize ; }
public void setConnectionPoolSize ( int connectionPoolSize ) { this . connectionPoolSize = connectionPoolSize ; }
public void s etTimeout ( int timeout ) {
RedissonConfig . timeout = timeout ;
}
public int g etSubscriptionsPerConnection ( ) { return subscriptionsPerConnection ; }
public void setSubscriptionsPerConnection ( int subscriptionsPerConnection ) { this . subscriptionsPerConnection = subscriptionsPerConnection ; }
// 重试配置
public int g etRetryAttempts ( ) {
return retryAttempts ;
}
public int getSubscriptionConnectionMinimumIdleSize ( ) { return subscriptionConnectionMinimumIdleSize ; }
public void s etSubscriptionConnectionMinimumIdleSize ( int subscriptionConnectionMinimumIdleSize ) { this . subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize ; }
public void s etRetryAttempts ( int retryAttempts ) {
RedissonConfig . retryAttempts = retryAttempts ;
}
public int g etSubscriptionConnectionPoolSize ( ) { return subscriptionConnectionPoolSize ; }
public void setSubscriptionConnectionPoolSize ( int subscriptionConnectionPoolSize ) { this . subscriptionConnectionPoolSize = subscriptionConnectionPoolSize ; }
public int getRetry Interval ( ) {
return retry Interval ;
}
public int getScan Interval ( ) { return scanInterval ; }
public void setScanInterval ( int scanInterval ) { this . scanInterval = scan Interval ; }
public void s etRetry Interval( int retry Interval) {
RedissonConfig . retry Interval = retry Interval;
}
public int g etDnsMonitoring Interval( ) { return dnsMonitoring Interval; }
public void setDnsMonitoringInterval ( int dnsMonitoringInterval ) { this . dnsMonitoring Interval = dnsMonitoring Interval; }
// 连接池配置
public int g etConnectionMinimumIdleSize ( ) {
return connectionMinimumIdleSize ;
}
public int getThreads ( ) { return threads ; }
public void s etThreads ( int threads ) { this . threads = threads ; }
public void s etConnectionMinimumIdleSize ( int connectionMinimumIdleSize ) {
RedissonConfig . connectionMinimumIdleSize = connectionMinimumIdleSize ;
}
public int getConnectionPoolSize ( ) {
return connectionPoolSize ;
}
public void setConnectionPoolSize ( int connectionPoolSize ) {
RedissonConfig . connectionPoolSize = connectionPoolSize ;
}
public int getSubscriptionsPerConnection ( ) {
return subscriptionsPerConnection ;
}
public void setSubscriptionsPerConnection ( int subscriptionsPerConnection ) {
RedissonConfig . subscriptionsPerConnection = subscriptionsPerConnection ;
}
public int getSubscriptionConnectionMinimumIdleSize ( ) {
return subscriptionConnectionMinimumIdleSize ;
}
public void setSubscriptionConnectionMinimumIdleSize ( int subscriptionConnectionMinimumIdleSize ) {
RedissonConfig . subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize ;
}
public int getSubscriptionConnectionPoolSize ( ) {
return subscriptionConnectionPoolSize ;
}
public void setSubscriptionConnectionPoolSize ( int subscriptionConnectionPoolSize ) {
RedissonConfig . subscriptionConnectionPoolSize = subscriptionConnectionPoolSize ;
}
// 其他配置
public int getDnsMonitoringInterval ( ) {
return dnsMonitoringInterval ;
}
public void setDnsMonitoringInterval ( int dnsMonitoringInterval ) {
RedissonConfig . dnsMonitoringInterval = dnsMonitoringInterval ;
}
public int getThread ( ) {
return thread ;
}
public void setThread ( int thread ) {
RedissonConfig . thread = thread ;
}
public static String getCodec ( ) {
return codec ;
}
public void setCodec ( String codec ) {
RedissonConfig . codec = codec ;
}
public String g etCodec ( ) { return codec ; }
public void setCodec ( String codec ) { this . codec = codec ; }
}