2020-08-08

java连接redis的三种方式

1 jedis

maven依赖

  
      redis.clients
      jedis
      2.9.1
 

注意在于springboot中默认使用的是lettuce方式,如果需要使用jedis,则需要将lecttuce排除,并引入jedis,同时jedis的版本要小于3.0;

2 lettuce

maven依赖


    io.lettuce
    lettuce-core-->
    5.3.0.RELEASE
 
 
    org.apache.commons
    commons-pool2
    2.8.0

注意使用连接池时,需要引入common-pool2依赖,此种方式是springboot的默认方式;

3 redission

此方式有免费版和付费版,使用redission,用户只需要关注业务逻辑。redission除了提供redis的基本命令之外,还提供了如分布式锁 ,分布式服务,分布式集合等功能。具体参考:https://github.com/redisson/redisson/wiki/

maven依赖:


   org.redisson
   redisson
   3.13.3

4 自定义spring-boot-starter结合redission

4.1 新建spring boot 项目,加入如下依赖


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

4.4 定义自动加载并打包

在resources目录下新建META-INF文件夹,然后新建spring.factories文件,添加一下内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.tiger.springboot.redission.RedissionConfiguration

执行:mvn clean install

4.5 使用

在引入redission的spring-boot-starter包时,还需要引入以下两个包,不然程序会出错

 
    de.ruedigermoeller
    fst
    2.57

 
    io.micrometer
    micrometer-core
    1.5.3

5 三种连接方式的测试

单线程执行set命令,非管道操作,执行耗时:

2020-08-08_第1张图片

你可能感兴趣的:(java)