CodisLabs / jodis

A java client for codis based on Jedis and Curator
MIT License
216 stars 97 forks source link

jodis整合spring session的问题 #48

Closed piaohao closed 5 years ago

piaohao commented 6 years ago

参照作者给的例子,springboot 项目 接入 jodis,项目启用了spring session,启动的时候报错:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/boot/autoconfigure/session/RedisSessionConfiguration$SpringBootRedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Unable to configure Redis to keyspace notifications. See http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-sessiondestroyedevent
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1589)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
    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:759)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
    at com.jinbaozheng.pufa.film.PufaApp.main(PufaApp.java:29)
Caused by: java.lang.IllegalStateException: Unable to configure Redis to keyspace notifications. See http://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-sessiondestroyedevent
    at org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction.getNotifyOptions(ConfigureNotifyKeyspaceEventsAction.java:81)
    at org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction.configure(ConfigureNotifyKeyspaceEventsAction.java:55)
    at org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration$EnableRedisKeyspaceNotificationsInitializer.afterPropertiesSet(RedisHttpSessionConfiguration.java:251)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1648)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1585)
    ... 16 common frames omitted
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: ERR handle request, command 'CONFIG' is not allowed; nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR handle request, command 'CONFIG' is not allowed
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:64)
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:41)
    at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37)
    at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:242)
    at org.springframework.data.redis.connection.jedis.JedisConnection.getConfig(JedisConnection.java:603)
    at org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction.getNotifyOptions(ConfigureNotifyKeyspaceEventsAction.java:74)
    ... 20 common frames omitted
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR handle request, command 'CONFIG' is not allowed
    at redis.clients.jedis.Protocol.processError(Protocol.java:127)
    at redis.clients.jedis.Protocol.process(Protocol.java:161)
    at redis.clients.jedis.Protocol.read(Protocol.java:215)
    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340)
    at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:276)
    at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:269)
    at redis.clients.jedis.Jedis.configGet(Jedis.java:2630)
    at org.springframework.data.redis.connection.jedis.JedisConnection.getConfig(JedisConnection.java:601)
    ... 21 common frames omitted

大概意思是 不支持 config命令, 请问作者 有什么好的解决方案没有

piaohao commented 6 years ago

而且spring session 处理session是通过 pub/sub的模式,jodis也是不支持的

toruneko commented 6 years ago
package org.springframework.session.data.redis;

public class CodisOperationsSessionRepository extends RedisOperationsSessionRepository {

    public CodisOperationsSessionRepository(RedisConnectionFactory redisConnectionFactory) {
        super(redisConnectionFactory);
    }

    public CodisOperationsSessionRepository(RedisOperations<Object, Object> sessionRedisOperations) {
        super(sessionRedisOperations);
    }

    @Override
    public void save(RedisOperationsSessionRepository.RedisSession session) {
        session.setNew(false);
        super.save(session);
    }
}

是的,spring session有个pub/sub。所以我们通过这个绕过了。

kinggggg commented 5 years ago

那这个问题如何解决呢?只能配置Codis集群?还是修改项目的代码?

piaohao commented 5 years ago

那这个问题如何解决呢?只能配置Codis集群?还是修改项目的代码?

楼上给出了session 的解决方案,重写redis存储方式即可, 但最终出于兼容性问题,我们还是放弃了codis

kinggggg commented 5 years ago

那这个问题如何解决呢?只能配置Codis集群?还是修改项目的代码?

楼上给出了session 的解决方案,重写redis存储方式即可, 但最终出于兼容性问题,我们还是放弃了codis

那您的做法不修改代码,将Codis换成了redis集群了吧?

piaohao commented 5 years ago

第一阶段我们使用了redis cluster集群,但线上运行半年发现,redis cluster并不稳定,莫名其妙的会挂掉,而且故障转移配置较为麻烦,需要较高的运维水平,于是我们放弃了redis cluster; 第二阶段我们改用阿里云的redis, master-slave 方式, 运行到现在,未曾出现过问题,4G的redis。

kinggggg commented 5 years ago

第一阶段我们使用了redis cluster集群,但线上运行半年发现,redis cluster并不稳定,莫名其妙的会挂掉,而且故障转移配置较为麻烦,需要较高的运维水平,于是我们放弃了redis cluster; 第二阶段我们改用阿里云的redis, master-slave 方式, 运行到现在,未曾出现过问题,4G的redis。

了解了!十分感谢您耐心的解答!Good!

Burt-L commented 5 years ago

我把spring session切换成了jdbc模式,就ok了

piaohao commented 5 years ago

我把spring session切换成了jdbc模式,就ok了

高并发系统可不敢这么搞哦

Burt-L commented 5 years ago

我把spring session切换成了jdbc模式,就ok了

高并发系统可不敢这么搞哦

没办法,退而求其次,先上了再优化