学习Spring-Session+Redis实现session共享

本文介绍如何使用Spring Session结合Redis实现跨服务器的session共享,包括依赖添加、配置及使用示例。

1、添加依赖

<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
  <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>

2、配置

spring-mvc.xml:

<bean id="redisHttpSessionConfiguration"
      class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="100" />
    <property name="maxIdle" value="10" />
</bean>

<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    <property name="hostName" value="${redis_hostname}"/>
    <property name="port" value="${redis_port}"/>
    <property name="password" value="${redis_pwd}" />
    <property name="timeout" value="3000"/>
    <property name="usePool" value="true"/>
    <property name="poolConfig" ref="jedisPoolConfig"/>
</bean>

web.xml添加拦截器:

<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3、使用spring-session

只要使用标准的servlet api调用session,在底层就会通过Spring Session得到的,并且会存储到Redis或其他你所选择的数据源中。

这里是我写的一个demo:

/**
 * @author fengzp
 * @date 17/2/23下午3:19
 * @email fengzp@gzyitop.com
 * @company 广州易站通计算机科技有限公司
 */
@Controller
@RequestMapping(value = "index")
public class IndexController {

    private final Gson gson = new GsonBuilder().setDateFormat("yyyyMMddHHmmss").create();

    @RequestMapping(value = "login")
    public String login(HttpServletRequest request, String username){

        request.getSession().setAttribute("user", gson.toJson(new User(username,"123456")));

        return "login";
    }

    @RequestMapping(value = "index")
    public String index(HttpServletRequest request, Model model){

        User user = gson.fromJson(request.getSession().getAttribute("user").toString(), User.class);

        model.addAttribute("user", user);

        return "index";
    }
}

index.jsp:

第一个tomcat

<html>
<body>
<h2>Hello World!</h2>
<p>${user.username}</p>
</body>
</html>

第二个tomcat

<html>
<body>
<h2>Hello World! i am the second!</h2>
<p>${user.username}</p>
</body>
</html>

测试

这里利用上一篇nginx负载配置的两个tomcat来测试。
首先访问 http://192.168.99.100/feng/index/login.htm?username=nginx 来触发生成session。

查看redis,发现session已经保存到redis。

访问 http://192.168.99.100/feng/index/index.htm 来读取session, 并刷新多次。

发现在负载的情况下读取session没问题,并且是同一个session,成功实现负载+session共享!

### 如何集成 Spring Session Data RedisRedisson 或者解决相关问题 #### 背景介绍 Spring Session 是一个用于管理 HTTP 会话的框架,支持多种存储后端(如 Redis)。通过使用 `spring-session-data-redis`,可以将用户的会话数据存储到 Redis 中[^1]。而 Redisson 则是一个基于 Netty 的高性能 Java 客户端库,提供了丰富的分布式对象和服务功能。 当尝试将两者结合起来时,可能会遇到一些挑战,因为它们都依赖于 Redis 进行操作,但实现方式不同。以下是关于如何结合使用这两种技术以及可能解决方案的具体说明: --- #### 解决方案一:配置独立的 Redis 实例 如果希望同时使用 `spring-session-data-redis` 和 Redisson,则可以通过为每种工具分配不同的 Redis 数据库实例来避免冲突。例如,在 Redis 配置文件中定义多个数据库索引,并分别指定给这两个组件。 ```properties # Application properties for spring-session-data-redis spring.redis.database=0 spring.session.store-type=redis # Configuration for Redisson client pointing to different database index redisson.config.singleServerConfig.address="redis://127.0.0.1:6379" redisson.config.singleServerConfig.database=1 ``` 这种方式能够有效隔离两者的键空间,防止互相干扰[^1]。 --- #### 解决方案二:自定义命名前缀策略 另一种方法是让两个模块共享同一个 Redis 实例,但是通过设置唯一的键名前缀区分各自的数据范围。对于 `spring-session-data-redis` 来说,默认情况下它已经会对所有的 session 键附加特定前缀;而对于 Redisson 用户则可以在初始化客户端的时候手动添加类似的机制。 下面展示了一个简单的例子演示如何修改 Redisson 的默认行为以便兼容这种需求: ```java import org.redisson.Redisson; import org.redisson.api.RBucket; import org.redisson.api.RedissonClient; import org.redisson.config.Config; public class CustomizedRedissonExample { public static void main(String[] args) { Config config = new Config(); // Set custom key prefix here. String customPrefix = "myapp:"; config.useSingleServer() .setAddress("redis://127.0.0.1:6379"); RedissonClient redisson = Redisson.create(config); RBucket<String> bucket = redisson.getBucket(customPrefix + "testKey"); bucket.set("value"); System.out.println(bucket.get()); } } ``` 这样做的好处是可以减少资源消耗并简化运维流程,缺点则是增加了开发复杂度[^2]。 --- #### 方案三:利用 Redis Cluster 提供更高可用性和扩展能力 考虑到实际生产环境中的高并发场景,建议采用 Redis Cluster 架构作为底层支撑平台。在这种模式下,即使单台节点发生故障也不会影响整体服务稳定性。更重要的是,由于集群内部实现了自动分片(sharding),因此无论你是运行了多少个应用程序副本还是部署了几套业务逻辑单元,都可以轻松应对海量请求压力而不必担心性能瓶颈问题出现。 需要注意的一点在于,无论是 Spring Boot Starter Redis 还是官方推荐使用的 Jedis/Lettuce 库版本都需要满足最低要求才能正常连接至 Clustersetup 上去工作[^3]。 --- #### 总结 综上所述,针对 “How To Integrate Spring-Session-Data-Redis With Redisson Or Solve Related Issues” 这个主题给出了三种可行的技术路线图解法。具体选择哪一种取决于项目实际情况比如团队技术水平、预算成本等因素综合考量之后再做决定最为合适不过啦! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值