将 spring-session 从 1.0.0.RC1 升级到 1.0.0.RELEASE 时出现 JedisDataException
JedisDataException when upgrading spring-session from 1.0.0.RC1 to 1.0.0.RELEASE
我们正在尝试从 RC1 升级到 RELEASE,但现在出现以下异常:
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'CONFIG'
at redis.clients.jedis.Protocol.processError(Protocol.java:100) ~[Protocol.class:na]
at redis.clients.jedis.Protocol.process(Protocol.java:118) ~[Protocol.class:na]
at redis.clients.jedis.Protocol.read(Protocol.java:187) ~[Protocol.class:na]
at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:212) ~[Connection.class:na]
at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:205) ~[Connection.class:na]
at redis.clients.jedis.Jedis.configGet(Jedis.java:2701) ~[Jedis.class:na]
at org.springframework.data.redis.connection.jedis.JedisConnection.getConfig(JedisConnection.java:531) ~[JedisConnection.class:1.3.0.RELEASE]
... 29 common frames omitted
这是我的会话配置:
@EnableRedisHttpSession
public class SessionConfig {
private static final int SESSION_EXPIRATION_TIME = 28800;
@Autowired
private Environment env;
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(env.getProperty("reddis.host"));
jedisConnectionFactory.setPort(env.getProperty("reddis.port", Integer.class));
return jedisConnectionFactory;
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
public RedisOperationsSessionRepository sessionRepository() {
RedisOperationsSessionRepository redisOperationsSessionRepository = new RedisOperationsSessionRepository(connectionFactory());
redisOperationsSessionRepository.setDefaultMaxInactiveInterval(SESSION_EXPIRATION_TIME);
return redisOperationsSessionRepository;
}
}
我们将 redis 2.8.6 与 AWS ElastiCache、spring 框架 4.1.4、spring-data-redis 1.3.0.RELEASE 和 jedis 客户端 2.4.1 一起使用。
知道我们为什么会遇到这个问题吗?
谢谢!
您正在经历 this bug。简而言之,Spring Session 正在尝试为您配置 Redis,而 AWS 禁止配置 Redis(出于安全原因)。
要解决此问题,您可以将 EnableRedisHttpSession
替换为 @Import(Issue124Config.class)
和以下配置:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.session.ExpiringSession;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.data.redis.SessionMessageListener;
import org.springframework.session.web.http.HttpSessionStrategy;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.util.ClassUtils;
@Configuration
public class Issue124Config {
@Value("${spring.session.maxInactive ?: 1800}")
private Integer maxInactiveIntervalInSeconds;
private HttpSessionStrategy httpSessionStrategy;
@Bean
public RedisTemplate<String,ExpiringSession> sessionRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
@Bean
public RedisOperationsSessionRepository sessionRepository(RedisTemplate<String, ExpiringSession> sessionRedisTemplate) {
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate);
sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds);
return sessionRepository;
}
@Bean
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
if(httpSessionStrategy != null) {
sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
}
return sessionRepositoryFilter;
}
@Autowired(required = false)
public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {
this.httpSessionStrategy = httpSessionStrategy;
}
}
我们正在尝试从 RC1 升级到 RELEASE,但现在出现以下异常:
Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR unknown command 'CONFIG'
at redis.clients.jedis.Protocol.processError(Protocol.java:100) ~[Protocol.class:na]
at redis.clients.jedis.Protocol.process(Protocol.java:118) ~[Protocol.class:na]
at redis.clients.jedis.Protocol.read(Protocol.java:187) ~[Protocol.class:na]
at redis.clients.jedis.Connection.getBinaryMultiBulkReply(Connection.java:212) ~[Connection.class:na]
at redis.clients.jedis.Connection.getMultiBulkReply(Connection.java:205) ~[Connection.class:na]
at redis.clients.jedis.Jedis.configGet(Jedis.java:2701) ~[Jedis.class:na]
at org.springframework.data.redis.connection.jedis.JedisConnection.getConfig(JedisConnection.java:531) ~[JedisConnection.class:1.3.0.RELEASE]
... 29 common frames omitted
这是我的会话配置:
@EnableRedisHttpSession
public class SessionConfig {
private static final int SESSION_EXPIRATION_TIME = 28800;
@Autowired
private Environment env;
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(env.getProperty("reddis.host"));
jedisConnectionFactory.setPort(env.getProperty("reddis.port", Integer.class));
return jedisConnectionFactory;
}
@Bean
public HttpSessionStrategy httpSessionStrategy() {
return new HeaderHttpSessionStrategy();
}
@Bean
public RedisOperationsSessionRepository sessionRepository() {
RedisOperationsSessionRepository redisOperationsSessionRepository = new RedisOperationsSessionRepository(connectionFactory());
redisOperationsSessionRepository.setDefaultMaxInactiveInterval(SESSION_EXPIRATION_TIME);
return redisOperationsSessionRepository;
}
}
我们将 redis 2.8.6 与 AWS ElastiCache、spring 框架 4.1.4、spring-data-redis 1.3.0.RELEASE 和 jedis 客户端 2.4.1 一起使用。
知道我们为什么会遇到这个问题吗?
谢谢!
您正在经历 this bug。简而言之,Spring Session 正在尝试为您配置 Redis,而 AWS 禁止配置 Redis(出于安全原因)。
要解决此问题,您可以将 EnableRedisHttpSession
替换为 @Import(Issue124Config.class)
和以下配置:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.session.ExpiringSession;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.data.redis.SessionMessageListener;
import org.springframework.session.web.http.HttpSessionStrategy;
import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.util.ClassUtils;
@Configuration
public class Issue124Config {
@Value("${spring.session.maxInactive ?: 1800}")
private Integer maxInactiveIntervalInSeconds;
private HttpSessionStrategy httpSessionStrategy;
@Bean
public RedisTemplate<String,ExpiringSession> sessionRedisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
@Bean
public RedisOperationsSessionRepository sessionRepository(RedisTemplate<String, ExpiringSession> sessionRedisTemplate) {
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate);
sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds);
return sessionRepository;
}
@Bean
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
if(httpSessionStrategy != null) {
sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
}
return sessionRepositoryFilter;
}
@Autowired(required = false)
public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) {
this.httpSessionStrategy = httpSessionStrategy;
}
}