redis相关

2018-11-05  本文已影响0人  我已不是少年郎
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分布式锁的时候暴露的,折腾我一下午。

上一篇下一篇

猜你喜欢

热点阅读