Redis主從加哨兵的部署詳見http://www.cnblogs.com/dupang/p/6414365.html
spring-data-redis和jedis集成代碼總體結構
代碼地址https://github.com/dupang/redistestwithspring
pom.xml
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>redistest</groupId> <artifactId>springredis</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>springredis Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <springframework.version>4.3.6.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.8.0.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> </dependencies> <build> <finalName>springredis</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
RedisTest.java
package com.dupang.redis; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by Administrator on 2017/2/17. */ public class RedisTest { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/spring-redisSentine.xml"); RedisUtil redisUtil = (RedisUtil) ac.getBean("redisUtil"); String ss = redisUtil.get("user.uid.1"); System.out.printf(ss); } }
RedisUtil.java
package com.dupang.redis; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.concurrent.TimeUnit; public class RedisUtil { private StringRedisTemplate redisTemplate; public RedisUtil(StringRedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; } public Boolean add(String key,String value){ Boolean rt=Boolean.FALSE; rt=redisTemplate.boundValueOps(key).setIfAbsent(value); if(rt) { redisTemplate.expire(key, 30L, TimeUnit.MINUTES); } return rt; } public Boolean add(String key,String value,long expire,TimeUnit timeUnit){ Boolean rt=Boolean.FALSE; rt=redisTemplate.boundValueOps(key).setIfAbsent(value); if(rt) { redisTemplate.expire(key, expire, timeUnit); } return rt; } public String get(String key){ return redisTemplate.boundValueOps(key).get(); } public void delete(String key){ redisTemplate.delete(key); } public String getAndRemove(String key){ String rt=redisTemplate.boundValueOps(key).get(); redisTemplate.delete(key); return rt; } public Boolean hasKey(String key){ return redisTemplate.hasKey(key); } }
spring-redisSentine.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:redis="http://www.springframework.org/schema/redis" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis-1.0.xsd"> <context:property-placeholder location="classpath:app.properties" /> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大空閑連接數 --> <property name="maxIdle" value="${redis.adapter.maxIdle}" /> <!-- 最小空閑連接數 --> <property name="minIdle" value="${redis.adapter.minIdle}" /> <!-- 在獲取連接的時候檢查有效性 --> <property name="testOnBorrow" value="${redis.adapter.testOnBorrow}" /> <!-- return 一個jedis實例給pool時,是否檢查連接可用性 (ping()) --> <property name="testOnReturn" value="${redis.adapter.testOnReturn}" /> <!-- idle狀態監測用異步線程evict進行檢查, --> <property name="testWhileIdle" value="${redis.adapter.testWhileIdle}" /> <!-- 一次最多evict的pool里的jedis實例個數 --> <property name="numTestsPerEvictionRun" value="${redis.adapter.numTestsPerEvictionRun}" /> <!-- test idle 線程的時間間隔 --> <property name="timeBetweenEvictionRunsMillis" value="${redis.adapter.timeBetweenEvictionRunsMillis}" /> </bean> <bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration"> <!-- master名稱 sentinel.conf里面配置的主節點名稱 --> <constructor-arg name="master" value="${redis.adapter.masterName}" /> <!-- sentinel的ip和端口列表 --> <constructor-arg name="sentinelHostAndPorts"> <set> <value>${redis.adapter.sentinel1}</value> <value>${redis.adapter.sentinel2}</value> <value>${redis.adapter.sentinel3}</value> </set> </constructor-arg> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <constructor-arg ref="sentinelConfig" /> <constructor-arg ref="jedisPoolConfig" /> </bean> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory" /> </bean> <bean id="redisUtil" class="com.dupang.redis.RedisUtil"> <constructor-arg name="redisTemplate" ref="redisTemplate"/> </bean> </beans>
app.properties
#redis redis.adapter.maxIdle=100 redis.adapter.minIdle=10 redis.adapter.testOnBorrow=true redis.adapter.testOnReturn=true redis.adapter.testWhileIdle=true redis.adapter.numTestsPerEvictionRun=10 redis.adapter.timeBetweenEvictionRunsMillis=60000 redis.adapter.masterName=mymaster redis.adapter.sentinel1=127.0.0.1:26379 redis.adapter.sentinel2=127.0.0.1:26389 redis.adapter.sentinel3=127.0.0.1:26399
遇到的問題
在運行測試類時報錯,內容如下
/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/bin/java -Didea.launcher.port=7533 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/lib/tools.jar:/Users/duguanxin/IdeaProjects/redistestwithspring/target/classes:/Users/duguanxin/.m2/repository/org/springframework/spring-context/4.3.6.RELEASE/spring-context-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-aop/4.3.6.RELEASE/spring-aop-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-beans/4.3.6.RELEASE/spring-beans-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-core/4.3.6.RELEASE/spring-core-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-expression/4.3.6.RELEASE/spring-expression-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-context-support/4.3.6.RELEASE/spring-context-support-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-tx/4.3.6.RELEASE/spring-tx-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-web/4.3.6.RELEASE/spring-web-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/junit/junit/4.12/junit-4.12.jar:/Users/duguanxin/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-test/4.3.6.RELEASE/spring-test-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/data/spring-data-redis/1.8.0.RELEASE/spring-data-redis-1.8.0.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/data/spring-data-keyvalue/1.2.0.RELEASE/spring-data-keyvalue-1.2.0.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/data/spring-data-commons/1.13.0.RELEASE/spring-data-commons-1.13.0.RELEASE.jar:/Users/duguanxin/.m2/repository/org/springframework/spring-oxm/4.3.6.RELEASE/spring-oxm-4.3.6.RELEASE.jar:/Users/duguanxin/.m2/repository/org/slf4j/slf4j-api/1.7.22/slf4j-api-1.7.22.jar:/Users/duguanxin/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.22/jcl-over-slf4j-1.7.22.jar:/Users/duguanxin/.m2/repository/redis/clients/jedis/2.9.0/jedis-2.9.0.jar:/Users/duguanxin/.m2/repository/org/apache/commons/commons-pool2/2.4.2/commons-pool2-2.4.2.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain com.dupang.redis.RedisTest SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 二月 19, 2017 10:34:30 上午 redis.clients.jedis.JedisSentinelPool initSentinels 信息: Trying to find master from available Sentinels... 二月 19, 2017 10:34:35 上午 redis.clients.jedis.JedisSentinelPool initSentinels 警告: Cannot get master address from sentinel running @ 192.168.2.101:26379. Reason: redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.. Trying next one. 二月 19, 2017 10:34:35 上午 redis.clients.jedis.JedisSentinelPool initSentinels 警告: Cannot get master address from sentinel running @ 192.168.2.101:26389. Reason: redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.. Trying next one. 二月 19, 2017 10:34:35 上午 redis.clients.jedis.JedisSentinelPool initSentinels 警告: Cannot get master address from sentinel running @ 192.168.2.101:26399. Reason: redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.. Trying next one. Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jedisConnectionFactory' defined in class path resource [spring-redisSentine.xml]: Invocation of init method failed; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: All sentinels down, cannot determine where is mymaster master is running... at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.dupang.redis.RedisTest.main(RedisTest.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) Caused by: redis.clients.jedis.exceptions.JedisConnectionException: All sentinels down, cannot determine where is mymaster master is running... at redis.clients.jedis.JedisSentinelPool.initSentinels(JedisSentinelPool.java:180) at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:95) at redis.clients.jedis.JedisSentinelPool.<init>(JedisSentinelPool.java:76) at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createRedisSentinelPool(JedisConnectionFactory.java:263) at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.createPool(JedisConnectionFactory.java:248) at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.afterPropertiesSet(JedisConnectionFactory.java:237) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ... 17 more Process finished with exit code 1
居然報所有哨兵都down掉的錯誤,而我確認所有這些哨兵都正常着,百度看看,說是防火牆的問題。但是我的防火牆就沒開,看來也不是這個問題。后來發現了上面打印的警告信息。
Cannot get master address from sentinel running @ 192.168.2.101:26399. Reason: redis.clients.jedis.exceptions.JedisDataException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.. Trying next one
這是因為哨兵的配置文件里的保護模式啟動了。所以又因為沒有綁定可以訪問的ip和設置訪問密碼,就不允許從外部訪問。
我們的哨兵明明是127的地址,應該訪問127.0.0.1:26379才對啊,這是因為redis內部把127的地址轉換成了192.168.2.101了,也就是你的本機的ip地址。所以訪問192的地址就相當於從外部訪問你的哨兵。
根據它的1,2,3,4的提示,你只要滿足其中一個就行。於是我就把三個哨兵的sentinel.conf配置文件中的保護模式改為禁用就行了
# *** 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
這樣再訪問就ok了。
插播個廣告

老丈人家的粉皮兒,農產品,沒有亂七八糟的添加劑,歡迎惠顧