在 Spring MVC 应用程序中集成 Redis 进行会话管理?

问题描述 投票:0回答:1

我目前在 Tomcat 9 上部署了一个 Spring MVC 应用程序,我希望通过集成 Redis 来增强其会话管理。该应用程序当前使用 Spring Session 和 Tomcat 的默认会话管理,但我们希望切换到 Redis 以获得更好的可扩展性和持久性。

以下是我们当前设置和我们打算实施的更改的概述:

当前设置:

<!-- Dependencies for Spring Session with Redis -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-core</artifactId>
    <version>2.7.4</version>
</dependency>
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>2.7.4</version>
</dependency>
<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.3.1.RELEASE</version>
</dependency>

目标:

在Spring MVC应用程序中实现基于Redis的会话管理。 使用 Redis 确保会话数据的可扩展性和持久性。 到目前为止我所做的:

添加了 Spring Session 与 Redis 的必要依赖关系(使用 Lettuce 作为 Redis 客户端)。 配置 Spring Session 以使用 Redis 进行会话管理。

遇到的问题:

虽然我在配置 Redis 进行会话管理方面取得了进展,但在设置会话 ID 解析器和正确配置 Redis 连接方面遇到了问题。当我使用 redis-cli 检查 redis 数据时,我可以创建会话。我不确定我当前的配置是否正确,或者是否需要采取其他步骤来确保一切顺利进行。

代码片段:

@PropertySource(value = "file:${APP_CONFIG}/redis.properties", ignoreResourceNotFound = false)
@EnableRedisHttpSession(redisNamespace = "spring:session:demo", cleanupCron = "0 */5 * * * ?", flushMode = FlushMode.IMMEDIATE, saveMode = SaveMode.ALWAYS)
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {

    @Value("${redis.port}")
    private Integer redisPort;

    @Value("${redis.host}")
    private String redisHost;

    @Value("${redis.pass}")
    private String redisPassword;

    private static final Logger log = LoggerFactory.getLogger(SessionConfig.class);

    @Bean
    @Primary
    public LettuceConnectionFactory redisConnectionFactory() {
        log.error("Creating LettuceConnectionFactory with Redis host: {} and port: {}", redisHost, redisPort);
        final RedisStandaloneConfiguration redisStandaloneConfig = new RedisStandaloneConfiguration();
        redisStandaloneConfig.setHostName(redisHost);
        redisStandaloneConfig.setPort(redisPort);
        redisStandaloneConfig.setPassword(redisPassword);
        final LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfig);
        // lettuceConnectionFactory.setValidateConnection(true);
        lettuceConnectionFactory.setEagerInitialization(true);
        lettuceConnectionFactory.afterPropertiesSet();
        return lettuceConnectionFactory;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public HttpSessionIdResolver httpSessionIdResolver() {
        CookieHttpSessionIdResolver resolver = new CookieHttpSessionIdResolver();
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setCookieName("JSESSIONID"); //
        cookieSerializer.setCookiePath("/");
        cookieSerializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
        cookieSerializer.setUseBase64Encoding(true);
        resolver.setCookieSerializer(cookieSerializer);
        return resolver;
    }
}

观察结果:

多个 JSESSIONID 值:在浏览器中加载登录页面时,我注意到生成了两个 JSESSIONID 值。一个似乎是由 Redis 创建的,而另一个似乎与 Tomcat 的会话管理机制相关。

Redis 会话 ID 的一致性:身份验证成功后,我已验证从 Redis 检索到的会话 ID 是否与数据库中存储的会话 ID 相匹配。

不一致的会话检索:在我的代码的某些部分中,当尝试使用 RequestContextHolder 访问会话时,我获取的是 Tomcat 会话 ID(JSESSIONID 值),而不是由 Redis 管理的会话 ID。

在下面的代码中,我获取了 Redis 生成的会话 ID:

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        HttpSession session = request.getSession(true);
//other codes
    }

在下面,我得到了 Tomcat 会话 JSESSIONID:

ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpSession session = requestAttributes.getRequest().getSession();
java spring-mvc session tomcat redis
1个回答
0
投票

请检查您的项目中的依赖项。 pom.xml 或 gradle.build 有问题。您在项目中使用多个会话尝试将其删除

© www.soinside.com 2019 - 2024. All rights reserved.