redis相关
1、centos下登录客户端
-h 代表IP地址
-p 代表端口
-a 代表密码,如果含有! 、#等特殊字符要在前面加"\"如下:
./redis-cli -h 127.0.0.1 -p 3690 -a **\!**
2、使用redisTemplate来集成redis的订阅发布功能
由于我是直接用redis提供的客户端模拟发布数据,而spring集成的默认是jdk的序列方式,
这里要注意需要配置序列化为redis的序列化方式,具体是String或者其他看自己业务要求。
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
否则会报如下错误
2018-11-05 16:14:37,053 - Execution of JMS message listener failed, and no ErrorHandler has been set.
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 2D312C61
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:41)
at com.RedisMessageListener.onMessage(RedisMessageListener.java:45)
at org.springframework.data.redis.listener.RedisMessageListenerContainer.executeListener(RedisMessageListenerContainer.java:245)
at org.springframework.data.redis.listener.RedisMessageListenerContainer.processMessage(RedisMessageListenerContainer.java:235)
at org.springframework.data.redis.listener.RedisMessageListenerContainer$1.run(RedisMessageListenerContainer.java:960)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.StreamCorruptedException: invalid stream header: 2D312C61
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:78)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:36)
at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:39)
... 12 more
Caused by: java.io.StreamCorruptedException: invalid stream header: 2D312C61
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:862)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:354)
at org.springframework.core.ConfigurableObjectInputStream.<init>(ConfigurableObjectInputStream.java:63)
at org.springframework.core.ConfigurableObjectInputStream.<init>(ConfigurableObjectInputStream.java:49)
at org.springframework.core.serializer.DefaultDeserializer.deserialize(DefaultDeserializer.java:68)
at org.springframework.core.serializer.support.DeserializingConverter.convert(DeserializingConverter.java:73)
... 14 more
已下是redis完整配置
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.pool.maxTotal}"/>
<property name="maxIdle" value="${redis.pool.maxIdle}"/>
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}"/>
</bean>
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.password}"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="valueSerializer" ref="stringRedisSerializer"/>
</bean>
<!-- 定义监听类 -->
<bean id="redisMessageListener" class="com.RedisMessageListener">
<property name="redisTemplate" ref="redisTemplate"/>
</bean>
<!-- 定义监听容器 -->
<bean id="redisMessageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<!-- 任务执行器 -->
<property name="taskExecutor">
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="10"/>
</bean>
</property>
<!-- 消息监听器 -->
<property name="messageListeners">
<map>
<entry key-ref="redisMessageListener">
<list>
<!-- <bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="chat1" />
</bean>
<bean class="org.springframework.data.redis.listener.ChannelTopic">
<constructor-arg value="chat2" />
</bean> -->
<bean class="org.springframework.data.redis.listener.PatternTopic">
<constructor-arg value="abc/*" />
</bean>
</list>
</entry>
</map>
</property>
</bean>
3、订阅发布
查询所有订阅和发布
pubsub channels
模糊查询
abc/为topoc
pubsub channels abc/
发布
abc/state为topoc
-1,0102030405060708为数据内容
publish abc/state -1,0102030405060708
=======================2018.11.20更新=============================
以上文章配置有个地方有个误导
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<property name="valueSerializer" ref="stringRedisSerializer"/>
</bean>
其中property里只配置了valueSerializer,意思就是说key并没有用到这个StringRedisSerializer,这会引起有时候删除不掉key的问题。
就比如,用execute来执行的时候,直接添加了一个key,代码如下,如果再用
redisTemplate.delete("SNLock_lock");这时候是删除不掉的,因为序列化方式不一致。
redisTemplate.execute(new RedisCallback<Object>() {
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Boolean success = connection.setNX("SNLock_lock", "123456");
connection.close();
return success;
}
});
可以尝试改为
StringRedisSerializer serializer = new StringRedisSerializer();
Boolean success = connection.setNX(serializer.serialize("SNLock_lock"), serializer.serialize("123456"));
或者直接在配置中把
<property name="valueSerializer" ref="stringRedisSerializer"/>
改为
<property name="defaultSerializer" ref="stringRedisSerializer"/>
这个问题在做redis分布式锁的时候暴露的,折腾我一下午。