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