Redis-Spring Data整合Jedis

Spring整合Jedis

1.單實(shí)例

step1:毫無疑問植酥,首先需要在pom.xml中配置Jedis依賴

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

step2:在resources中添加settings.properties,配置redis相關(guān)屬性


#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只有簡單配置,如果需要增加其它配置項(xiàng)(如密碼等)材原,請自行參照J(rèn)edisPool的構(gòu)造方法進(jìn)行配置

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:啟動窿侈、運(yùn)行念秧、報(bào)錯

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

查看源碼發(fā)現(xiàn)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>

再次運(yùn)行聊闯,得到“Pong”的response結(jié)果,測試成功


Ping.png
2.配置Redis簡單主從復(fù)制

Jedis對redis的集群支持也很完善米诉,實(shí)例化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模式

僅僅配置了主從復(fù)制是不夠的菱蔬,沒有sentinel就不能實(shí)現(xiàn)故障轉(zhuǎn)移,redis集群就失去意義了史侣。
spring-data-redis對sentinel提供了很好的支持拴泌,詳細(xì)配置如下

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或者解除保護(hù)模式(生產(chǎn)環(huán)境下建議綁定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

否則會報(bào)錯:All sentinels down, cannot determine where is mymaster master is running...

4.配置Redis Cluster

Redis Cluster是3.0版本后的一種集群系統(tǒng)蚪腐,它實(shí)現(xiàn)了數(shù)據(jù)分片,解決了單機(jī)數(shù)據(jù)容量瓶頸問題税朴,同時也實(shí)現(xiàn)了高可用回季。

使用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已經(jīng)為我們封裝好了所有的設(shè)置正林,再通過org.springframework.data.redis.core.StringRedisTemplate泡一,就可以在代碼中很方便地對Redis進(jìn)行讀寫!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末觅廓,一起剝皮案震驚了整個濱河市精算,隨后出現(xiàn)的幾起案子秀撇,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件秆乳,死亡現(xiàn)場離奇詭異,居然都是意外死亡喜最,警方通過查閱死者的電腦和手機(jī)澜倦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篡殷,“玉大人钝吮,你說我怎么就攤上這事“辶桑” “怎么了奇瘦?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長劲弦。 經(jīng)常有香客問我耳标,道長,這世上最難降的妖魔是什么邑跪? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任次坡,我火速辦了婚禮呼猪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砸琅。我一直安慰自己宋距,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布症脂。 她就那樣靜靜地躺著谚赎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诱篷。 梳的紋絲不亂的頭發(fā)上沸版,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音兴蒸,去河邊找鬼视粮。 笑死,一個胖子當(dāng)著我的面吹牛橙凳,可吹牛的內(nèi)容都是我干的蕾殴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼岛啸,長吁一口氣:“原來是場噩夢啊……” “哼钓觉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起坚踩,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤荡灾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瞬铸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體批幌,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年嗓节,在試婚紗的時候發(fā)現(xiàn)自己被綠了荧缘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡拦宣,死狀恐怖截粗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸵隧,我是刑警寧澤绸罗,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站豆瘫,受9級特大地震影響珊蟀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜靡羡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一系洛、第九天 我趴在偏房一處隱蔽的房頂上張望俊性。 院中可真熱鬧略步,春花似錦描扯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杭煎,卻和暖如春恩够,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背羡铲。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工蜂桶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人也切。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓扑媚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雷恃。 傳聞我的和親對象是個殘疾皇子疆股,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345