美文网首页后端程序员Spring
Redis-Spring Data整合Jedis

Redis-Spring Data整合Jedis

作者: yuanzicheng | 来源:发表于2017-04-05 19:49 被阅读959次

    Spring整合Jedis

    1.单实例

    step1:毫无疑问,首先需要在pom.xml中配置Jedis依赖

            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.9.0</version>
            </dependency>
    

    step2:在resources中添加settings.properties,配置redis相关属性

    
    #jedisPoolConfig
    redis.minIdle=100
    redis.maxIdle=500
    redis.maxTotal=50000 
    redis.maxWaitMillis=10000  
    redis.testOnBorrow=true
    
    
    #jedisPool
    redis.host=127.0.0.1
    redis.port=6379
    redis.timeout=2000
    

    step3:在spring-context.xml配置JedisPoolConfig及JedisPool

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:component-scan base-package="service,dao"/>
    
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:settings.properties</value>
                </list>
            </property>
        </bean>
    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="maxTotal" value="${redis.maxTotal}" />
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
            <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
            <constructor-arg name="host" value="${redis.host}" />
            <constructor-arg name="port" value="${redis.port}" type="int" />
        </bean>
    
    </beans>
    

    JedisPool只有简单配置,如果需要增加其它配置项(如密码等),请自行参照JedisPool的构造方法进行配置

    JedisPool.png

    step4:在TestController中测试是否连接成功

    package controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    
    @Controller
    public class TestController {
    
        @Autowired
        private JedisPool jedisPool;
    
        @RequestMapping(value = "test",method = RequestMethod.GET,produces = "application/json;charset=utf-8")
        @ResponseBody
        public String test(){
            return jedisPool.getResource().ping();
        }
    
        public static void main(String[] args) {
            Jedis jedis = new Jedis("127.0.0.1",6379);
            System.out.println(jedis.ping());
        }
    
    }
    
    

    step5:启动、运行、报错

    nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool2/impl/GenericObjectPoolConfig
    

    查看源码发现JedisPoolConfig继承自GenericObjectPoolConfig

    package redis.clients.jedis;
    
    import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
    
    public class JedisPoolConfig extends GenericObjectPoolConfig {
        public JedisPoolConfig() {
            this.setTestWhileIdle(true);
            this.setMinEvictableIdleTimeMillis(60000L);
            this.setTimeBetweenEvictionRunsMillis(30000L);
            this.setNumTestsPerEvictionRun(-1);
        }
    }
    

    而GenericObjectPoolConfig在package org.apache.commons.pool2.impl中,所以需要引入commons-pool2依赖

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>2.4.2</version>
            </dependency>
    

    再次运行,得到“Pong”的response结果,测试成功


    Ping.png
    2.配置Redis简单主从复制

    Jedis对redis的集群支持也很完善,实例化SharedJedisPool即可

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:component-scan base-package="service,dao,redis"/>
    
    
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:settings.properties</value>
                </list>
            </property>
        </bean>
    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.maxTotal}" />
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="minIdle" value="${redis.minIdle}" />
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
    <!--
        <bean id="jedisPool" class="redis.clients.jedis.JedisPool" scope="singleton">
            <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
            <constructor-arg name="host" value="${redis.host}" />
            <constructor-arg name="port" value="${redis.port}" type="int" />
        </bean>
    -->
    
        <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">
            <constructor-arg index="0" ref="jedisPoolConfig" />
            <constructor-arg index="1">
                <list>
                    <bean class="redis.clients.jedis.JedisShardInfo">
                        <constructor-arg name="host" value="${redis.host1}" />
                        <constructor-arg name="port" value="${redis.port1}" />
                        <constructor-arg name="timeout" value="${redis.timeout}" />
                        <constructor-arg name="name" value="node1" />
                    </bean>
                    <bean class="redis.clients.jedis.JedisShardInfo">
                        <constructor-arg name="host" value="${redis.host2}" />
                        <constructor-arg name="port" value="${redis.port2}" />
                        <constructor-arg name="timeout" value="${redis.timeout}" />
                        <constructor-arg name="name" value="node2" />
                    </bean>
                </list>
            </constructor-arg>
        </bean>
    
    </beans>
    
    3.sentinel模式

    仅仅配置了主从复制是不够的,没有sentinel就不能实现故障转移,redis集群就失去意义了。
    spring-data-redis对sentinel提供了很好的支持,详细配置如下

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>me.com</groupId>
        <artifactId>springmvc</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <spring.version>4.3.0.RELEASE</spring.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>2.9.0</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-pool2</artifactId>
                <version>2.4.2</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-redis</artifactId>
                <version>1.8.0.RELEASE</version>
            </dependency>
        </dependencies>
    
    </project>
    

    settings.properties

    #jedisPoolConfig
    redis.maxTotal=50000 
    redis.maxIdle=500
    redis.minIdle=100
    redis.maxWaitMillis=10000 
    redis.testOnBorrow=true
    
    #redis-sentinel
    redis.sentinel=127.0.0.1:26379
    redis.master=mymaster
    

    spring-context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:component-scan base-package="service,dao,redis"/>
    
    
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <property name="locations">
                <list>
                    <value>classpath:settings.properties</value>
                </list>
            </property>
        </bean>
    
        <!-- ******************** Redis Start ******************** -->
    
        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.maxTotal}" />
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="minIdle" value="${redis.minIdle}" />
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
        <bean id="redisSentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
            <constructor-arg name="master" value="${redis.master}" />
            <constructor-arg name="sentinelHostAndPorts">
                <set>
                    <value>${redis.sentinel}</value>
                </set>
            </constructor-arg>
        </bean>
    
        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <!-- 如有密码可以用p:password指定 -->
            <constructor-arg ref="redisSentinelConfiguration" />
            <constructor-arg ref="jedisPoolConfig" />
        </bean>
    
    
        <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
            <property name="connectionFactory" ref="jedisConnectionFactory" />
        </bean>
    
        <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
    
    
        <!-- ******************** Redis End ******************** -->
    
    </beans>
    

    TestController

    package controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Controller
    public class TestController {
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        @RequestMapping(value = "test",method = RequestMethod.GET,produces = "application/json;charset=utf-8")
        @ResponseBody
        public String test(){
            stringRedisTemplate.opsForValue().set("key1","v1");
            return stringRedisTemplate.opsForValue().get("key1");
        }
    
    }
    
    

    另外,特别提醒:
    sentinel.conf配置文件中明确说明,需要绑定ip或者解除保护模式(生产环境下建议绑定ip)

    # *** IMPORTANT ***
    #
    # By default Sentinel will not be reachable from interfaces different than
    # localhost, either use the 'bind' directive to bind to a list of network
    # interfaces, or disable protected mode with "protected-mode no" by
    # adding it to this configuration file.
    #
    # Before doing that MAKE SURE the instance is protected from the outside
    # world via firewalling or other means.
    #
    # For example you may use one of the following:
    #
    # bind 127.0.0.1 192.168.1.1
    #
    # protected-mode no
    

    否则会报错:All sentinels down, cannot determine where is mymaster master is running...

    4.配置Redis Cluster

    Redis Cluster是3.0版本后的一种集群系统,它实现了数据分片,解决了单机数据容量瓶颈问题,同时也实现了高可用。

    使用Spring+Jedis配置Redis Cluster也非常简单。

        <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
            <property name="maxTotal" value="${redis.maxTotal}" />
            <property name="maxIdle" value="${redis.maxIdle}" />
            <property name="minIdle" value="${redis.minIdle}" />
            <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />
        </bean>
    
        <!--  配置redis cluster -->
        <bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
            <property name="clusterNodes">
                <set>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip1}"/>
                        <constructor-arg name="port" value="${redis.port1}"/>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip2}"/>
                        <constructor-arg name="port" value="${redis.port2}"/>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip3}"/>
                        <constructor-arg name="port" value="${redis.port3}"/>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip4}"/>
                        <constructor-arg name="port" value="${redis.port4}"/>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip5}"/>
                        <constructor-arg name="port" value="${redis.port5}"/>
                    </bean>
                    <bean class="org.springframework.data.redis.connection.RedisNode">
                        <constructor-arg name="host" value="${redis.ip6}"/>
                        <constructor-arg name="port" value="${redis.port6}"/>
                    </bean>
                </set>
            </property>
        </bean>
    
        <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
            <constructor-arg name="clusterConfig" ref="redisClusterConfiguration" />
            <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
        </bean>
    

    org.springframework.data.redis.connection.RedisClusterConfigurationorg.springframework.data.redis.connection.jedis.JedisConnectionFactory已经为我们封装好了所有的设置,再通过org.springframework.data.redis.core.StringRedisTemplate,就可以在代码中很方便地对Redis进行读写!

    相关文章

      网友评论

      • June0609:生产环境中Sentinel数量3+

      本文标题:Redis-Spring Data整合Jedis

      本文链接:https://www.haomeiwen.com/subject/sdjgottx.html