maven依赖
redis.clients
jedis
2.9.1
注意在于springboot中默认使用的是lettuce方式,如果需要使用jedis,则需要将lecttuce排除,并引入jedis,同时jedis的版本要小于3.0;
maven依赖
io.lettuce
lettuce-core -->
5.3.0.RELEASE
org.apache.commons
commons-pool2
2.8.0
注意使用连接池时,需要引入common-pool2依赖,此种方式是springboot的默认方式;
此方式有免费版和付费版,使用redission,用户只需要关注业务逻辑。redission除了提供redis的基本命令之外,还提供了如分布式锁 ,分布式服务,分布式集合等功能。具体参考:https://github.com/redisson/redisson/wiki/
maven依赖:
org.redisson
redisson
3.13.3
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-autoconfigure
org.springframework.boot
spring-boot-configuration-processor
org.redisson
redisson
3.13.3
4.2 定义redission相关属性配置:
import org.redisson.config.ReadMode;
import org.redisson.config.SubscriptionMode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.time.Duration;
/**
*
* @Date: 2020/8/4 23:37
* @Description:
* @Version: 1.0
**/
@ConfigurationProperties(prefix = "spring.redission")
public class RedissionProperties {
private String codec = "org.redisson.codec.FstCodec";
private int nettyThreads = 32;
private int threads = 16;
private Duration connectTimeout = Duration.ofMillis(10000);
private Duration idleConnectionTimeout = Duration.ofMillis(10000);
private Duration timeout = Duration.ofMillis(3000);
private int slaveConnectionMinimumIdleSize = 24;
private int slaveConnectionPoolSize = 64;
private Duration failedSlaveReconnectionInterval = Duration.ofMillis(3000);
private Duration failedSlaveCheckInterval = Duration.ofMillis(60000);
private int masterConnectionMinimumIdleSize = 24;
private int masterConnectionPoolSize = 64;
private ReadMode readMode = ReadMode.SLAVE;
private SubscriptionMode subscriptionMode = SubscriptionMode.SLAVE;
private Duration pingConnectionInterval = Duration.ofMillis(0);
private int connectionMinimumIdleSize = 24;
private int connectionPoolSize = 64;
private int subscriptionsPerConnection = 5;
private int subscriptionConnectionMinimumIdleSize = 1;
private int subscriptionConnectionPoolSize = 50;
private int retryAttempts = 3;
private Duration retryInterval = Duration.ofMillis(1500);
private String password;
private int database = 0;
private String loadBalancer = "org.redisson.connection.balancer.RoundRobinLoadBalancer";
private boolean keepAlive = false;
private boolean tcpNoDelay = false;
private Cluster cluster;
private Replicate replicate;
private Sentinel sentinel;
private MasterSlave masterSlave;
public String getCodec() {
return codec;
}
public void setCodec(String codec) {
this.codec = codec;
}
public int getNettyThreads() {
return nettyThreads;
}
public void setNettyThreads(int nettyThreads) {
this.nettyThreads = nettyThreads;
}
public int getThreads() {
return threads;
}
public void setThreads(int threads) {
this.threads = threads;
}
public Duration getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
}
public Duration getIdleConnectionTimeout() {
return idleConnectionTimeout;
}
public void setIdleConnectionTimeout(Duration idleConnectionTimeout) {
this.idleConnectionTimeout = idleConnectionTimeout;
}
public Duration getTimeout() {
return timeout;
}
public void setTimeout(Duration timeout) {
this.timeout = timeout;
}
public int getSlaveConnectionMinimumIdleSize() {
return slaveConnectionMinimumIdleSize;
}
public void setSlaveConnectionMinimumIdleSize(int slaveConnectionMinimumIdleSize) {
this.slaveConnectionMinimumIdleSize = slaveConnectionMinimumIdleSize;
}
public int getSlaveConnectionPoolSize() {
return slaveConnectionPoolSize;
}
public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) {
this.slaveConnectionPoolSize = slaveConnectionPoolSize;
}
public Duration getFailedSlaveReconnectionInterval() {
return failedSlaveReconnectionInterval;
}
public void setFailedSlaveReconnectionInterval(Duration failedSlaveReconnectionInterval) {
this.failedSlaveReconnectionInterval = failedSlaveReconnectionInterval;
}
public Duration getFailedSlaveCheckInterval() {
return failedSlaveCheckInterval;
}
public void setFailedSlaveCheckInterval(Duration failedSlaveCheckInterval) {
this.failedSlaveCheckInterval = failedSlaveCheckInterval;
}
public int getMasterConnectionMinimumIdleSize() {
return masterConnectionMinimumIdleSize;
}
public void setMasterConnectionMinimumIdleSize(int masterConnectionMinimumIdleSize) {
this.masterConnectionMinimumIdleSize = masterConnectionMinimumIdleSize;
}
public int getMasterConnectionPoolSize() {
return masterConnectionPoolSize;
}
public void setMasterConnectionPoolSize(int masterConnectionPoolSize) {
this.masterConnectionPoolSize = masterConnectionPoolSize;
}
public ReadMode getReadMode() {
return readMode;
}
public void setReadMode(ReadMode readMode) {
this.readMode = readMode;
}
public SubscriptionMode getSubscriptionMode() {
return subscriptionMode;
}
public void setSubscriptionMode(SubscriptionMode subscriptionMode) {
this.subscriptionMode = subscriptionMode;
}
public Duration getPingConnectionInterval() {
return pingConnectionInterval;
}
public void setPingConnectionInterval(Duration pingConnectionInterval) {
this.pingConnectionInterval = pingConnectionInterval;
}
public int getConnectionMinimumIdleSize() {
return connectionMinimumIdleSize;
}
public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {
this.connectionMinimumIdleSize = connectionMinimumIdleSize;
}
public int getConnectionPoolSize() {
return connectionPoolSize;
}
public void setConnectionPoolSize(int connectionPoolSize) {
this.connectionPoolSize = connectionPoolSize;
}
public int getSubscriptionsPerConnection() {
return subscriptionsPerConnection;
}
public void setSubscriptionsPerConnection(int subscriptionsPerConnection) {
this.subscriptionsPerConnection = subscriptionsPerConnection;
}
public int getSubscriptionConnectionMinimumIdleSize() {
return subscriptionConnectionMinimumIdleSize;
}
public void setSubscriptionConnectionMinimumIdleSize(int subscriptionConnectionMinimumIdleSize) {
this.subscriptionConnectionMinimumIdleSize = subscriptionConnectionMinimumIdleSize;
}
public int getSubscriptionConnectionPoolSize() {
return subscriptionConnectionPoolSize;
}
public void setSubscriptionConnectionPoolSize(int subscriptionConnectionPoolSize) {
this.subscriptionConnectionPoolSize = subscriptionConnectionPoolSize;
}
public int getRetryAttempts() {
return retryAttempts;
}
public void setRetryAttempts(int retryAttempts) {
this.retryAttempts = retryAttempts;
}
public Duration getRetryInterval() {
return retryInterval;
}
public void setRetryInterval(Duration retryInterval) {
this.retryInterval = retryInterval;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getLoadBalancer() {
return loadBalancer;
}
public void setLoadBalancer(String loadBalancer) {
this.loadBalancer = loadBalancer;
}
public boolean isKeepAlive() {
return keepAlive;
}
public void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
}
public boolean isTcpNoDelay() {
return tcpNoDelay;
}
public void setTcpNoDelay(boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
}
public Cluster getCluster() {
return cluster;
}
public void setCluster(Cluster cluster) {
this.cluster = cluster;
}
public Replicate getReplicate() {
return replicate;
}
public void setReplicate(Replicate replicate) {
this.replicate = replicate;
}
public Sentinel getSentinel() {
return sentinel;
}
public void setSentinel(Sentinel sentinel) {
this.sentinel = sentinel;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public MasterSlave getMasterSlave() {
return masterSlave;
}
public void setMasterSlave(MasterSlave masterSlave) {
this.masterSlave = masterSlave;
}
// cluster
public static class Cluster {
private boolean checkSlotsCoverage = true;
private String[] nodeAddresses;
private Duration scanInterval = Duration.ofMillis(1000);
public boolean isCheckSlotsCoverage() {
return checkSlotsCoverage;
}
public void setCheckSlotsCoverage(boolean checkSlotsCoverage) {
this.checkSlotsCoverage = checkSlotsCoverage;
}
public String[] getNodeAddresses() {
return nodeAddresses;
}
public void setNodeAddresses(String[] nodeAddresses) {
this.nodeAddresses = nodeAddresses;
}
public Duration getScanInterval() {
return scanInterval;
}
public void setScanInterval(Duration scanInterval) {
this.scanInterval = scanInterval;
}
}
// 单节点
private String address = "redis://127.0.0.1:6379";
// 主从
public static class Replicate {
private String[] nodeAddresses;
private Duration scanInterval = Duration.ofMillis(1000);
public String[] getNodeAddresses() {
return nodeAddresses;
}
public void setNodeAddresses(String[] nodeAddresses) {
this.nodeAddresses = nodeAddresses;
}
public Duration getScanInterval() {
return scanInterval;
}
public void setScanInterval(Duration scanInterval) {
this.scanInterval = scanInterval;
}
}
public static class MasterSlave {
private String masterAddress;
private String[] slaveAddresses;
public String getMasterAddress() {
return masterAddress;
}
public void setMasterAddress(String masterAddress) {
this.masterAddress = masterAddress;
}
public String[] getSlaveAddresses() {
return slaveAddresses;
}
public void setSlaveAddresses(String[] slaveAddresses) {
this.slaveAddresses = slaveAddresses;
}
}
// 哨兵
public static class Sentinel {
private String[] sentinelAddresses;
private String masterName;
private Duration scanInterval = Duration.ofMillis(1000);
private boolean checkSentinelsList = true;
public String[] getSentinelAddresses() {
return sentinelAddresses;
}
public void setSentinelAddresses(String[] sentinelAddresses) {
this.sentinelAddresses = sentinelAddresses;
}
public String getMasterName() {
return masterName;
}
public void setMasterName(String masterName) {
this.masterName = masterName;
}
public Duration getScanInterval() {
return scanInterval;
}
public void setScanInterval(Duration scanInterval) {
this.scanInterval = scanInterval;
}
public boolean isCheckSentinelsList() {
return checkSentinelsList;
}
public void setCheckSentinelsList(boolean checkSentinelsList) {
this.checkSentinelsList = checkSentinelsList;
}
}
}
redission有四种模式的配置: Cluster(redis集群)、Replicated(副本)、Single instance mode(redis单节点)、 Sentinel mode(redis哨兵)、Master slave mode(主从)
4.3 定义自动配置
import org.redisson.client.codec.Codec;
import org.redisson.config.*;
import org.redisson.connection.balancer.LoadBalancer;
/**
* @Auther:
* @Date: 2020/8/7 23:48
* @Description:
* @Version: 1.0
**/
public class RedissionConnectionConfiguration {
private RedissionProperties properties;
private Config standaloneConfig = null;
private Config replicateConfig = null;
private Config masterSlaveConfig = null;
private Config sentinelConfig = null;
private Config clutserConig = null;
public RedissionConnectionConfiguration(RedissionProperties properties) {
this.properties = properties;
}
protected Config getStandaloneConfig() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
if (standaloneConfig != null) {
return standaloneConfig;
}
this.standaloneConfig = new Config();
configSetting(this.standaloneConfig);
SingleServerConfig singleServerConfig = this.standaloneConfig.useSingleServer();
singleServerConfig.setDatabase(properties.getDatabase());
singleServerConfig.setAddress(properties.getAddress());
initBaseConfig(singleServerConfig);
return standaloneConfig;
}
protected Config getClusterConfig() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
if (clutserConig != null) {
return clutserConig;
}
if (properties.getCluster() == null) {
this.clutserConig = null;
} else {
this.clutserConig = new Config();
configSetting(clutserConig);
ClusterServersConfig clusterServersConfig = clutserConig.useClusterServers()
.addNodeAddress(properties.getCluster().getNodeAddresses())
.setScanInterval((int) properties.getCluster().getScanInterval().toMillis())
.setCheckSlotsCoverage(properties.getCluster().isCheckSlotsCoverage());
initBaseConfig(clusterServersConfig);
initBaseMasterSlaveServersConfig(clusterServersConfig);
}
return clutserConig;
}
protected Config getRelicateConfig() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
if (replicateConfig != null) {
return replicateConfig;
}
if (properties.getReplicate() == null) {
this.replicateConfig = null;
} else {
this.replicateConfig = new Config();
configSetting(replicateConfig);
ReplicatedServersConfig replicatedServersConfig = replicateConfig.useReplicatedServers()
.addNodeAddress(properties.getReplicate().getNodeAddresses());
initBaseConfig(replicatedServersConfig);
initBaseMasterSlaveServersConfig(replicatedServersConfig);
}
return replicateConfig;
}
protected Config getSentinalConfig() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
if (sentinelConfig != null) {
return sentinelConfig;
}
if (properties.getSentinel() == null) {
sentinelConfig = null;
} else {
sentinelConfig = new Config();
configSetting(sentinelConfig);
SentinelServersConfig sentinelServersConfig = sentinelConfig.useSentinelServers()
.addSentinelAddress(properties.getSentinel().getSentinelAddresses())
.setMasterName(properties.getSentinel().getMasterName())
.setScanInterval((int) properties.getSentinel().getScanInterval().toMillis())
.setCheckSentinelsList(properties.getSentinel().isCheckSentinelsList());
initBaseConfig(sentinelServersConfig);
initBaseMasterSlaveServersConfig(sentinelServersConfig);
}
return sentinelConfig;
}
protected Config masterSlaveConfig() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
if (masterSlaveConfig != null) {
return masterSlaveConfig;
}
if (properties.getMasterSlave() == null) {
masterSlaveConfig = null;
} else {
masterSlaveConfig = new Config();
configSetting(masterSlaveConfig);
MasterSlaveServersConfig masterSlaveServersConfig = masterSlaveConfig.useMasterSlaveServers()
.addSlaveAddress(properties.getMasterSlave().getSlaveAddresses())
.setMasterAddress(properties.getMasterSlave().getMasterAddress());
initBaseConfig(masterSlaveServersConfig);
initBaseMasterSlaveServersConfig(masterSlaveServersConfig);
}
return masterSlaveConfig;
}
private void configSetting(Config config) throws ClassNotFoundException, IllegalAccessException,
InstantiationException {
config.setCodec((Codec) Class.forName(properties.getCodec()).newInstance());
config.setNettyThreads(properties.getNettyThreads());
config.setThreads(properties.getThreads());
}
private void initBaseMasterSlaveServersConfig(BaseMasterSlaveServersConfig config) throws ClassNotFoundException,
IllegalAccessException, InstantiationException {
config.setLoadBalancer((LoadBalancer) Class.forName(properties.getLoadBalancer()).newInstance())
.setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize())
.setSlaveConnectionMinimumIdleSize(properties.getSlaveConnectionMinimumIdleSize())
.setSlaveConnectionPoolSize(properties.getSlaveConnectionPoolSize())
.setFailedSlaveReconnectionInterval((int) properties.getFailedSlaveReconnectionInterval().toMillis())
.setMasterConnectionMinimumIdleSize(properties.getMasterConnectionMinimumIdleSize())
.setMasterConnectionPoolSize(properties.getMasterConnectionPoolSize())
.setReadMode(properties.getReadMode())
.setSubscriptionMode(properties.getSubscriptionMode())
.setSubscriptionConnectionMinimumIdleSize(properties.getSubscriptionConnectionMinimumIdleSize())
.setSubscriptionConnectionPoolSize(properties.getSubscriptionConnectionPoolSize());
}
private void initBaseConfig(BaseConfig config) {
config.setConnectTimeout((int) properties.getConnectTimeout().toMillis())
.setIdleConnectionTimeout((int) properties.getIdleConnectionTimeout().toMillis())
.setTimeout((int) properties.getTimeout().toMillis())
.setRetryAttempts(properties.getRetryAttempts())
.setRetryInterval((int) properties.getRetryInterval().toMillis())
.setPassword(properties.getPassword())
.setSubscriptionsPerConnection(properties.getSubscriptionsPerConnection())
.setTcpNoDelay(properties.isTcpNoDelay())
.setKeepAlive(properties.isKeepAlive());
}
}
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Auther:
* @Date: 2020/8/4 23:46
* @Description:
* @Version: 1.0
**/
@Configuration
@EnableConfigurationProperties(RedissionProperties.class)
@ConditionalOnProperty(prefix = "spring.redission", value = "enabled", matchIfMissing = true)
public class RedissionConfiguration {
private static final Logger log = LoggerFactory.getLogger(RedissionConfiguration.class);
@Autowired
private RedissionProperties properties;
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() {
try {
RedissionConnectionConfiguration configuration = getRedissionConnectionConfiguration();
if (configuration.getRelicateConfig() != null) {
return Redisson.create(configuration.getRelicateConfig());
} else if (configuration.masterSlaveConfig() != null) {
return Redisson.create(configuration.masterSlaveConfig());
} else if (configuration.getSentinalConfig() != null) {
return Redisson.create(configuration.getSentinalConfig());
} else if (configuration.getClusterConfig() != null) {
return Redisson.create(configuration.getClusterConfig());
} else {
return Redisson.create(configuration.getStandaloneConfig());
}
} catch (Exception e) {
log.error("fail to create redission client", e);
}
return null;
}
private RedissionConnectionConfiguration getRedissionConnectionConfiguration() {
return new RedissionConnectionConfiguration(properties);
}
}
在resources目录下新建META-INF文件夹,然后新建spring.factories文件,添加一下内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.tiger.springboot.redission.RedissionConfiguration
执行:mvn clean install
在引入redission的spring-boot-starter包时,还需要引入以下两个包,不然程序会出错
de.ruedigermoeller
fst
2.57
io.micrometer
micrometer-core
1.5.3
5 三种连接方式的测试
单线程执行set命令,非管道操作,执行耗时: