SpringBoot实现Session缓存共享

本文介绍如何利用SpringBoot、Redis和Nginx实现Session数据的缓存共享及负载均衡,突破传统单机session限制,适用于分布式和集群环境。通过自定义Filter和存储容器操作类,无缝切换session管理,并提供具体实现步骤和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot+Redis+Nginx实现负载均衡以及Session缓存共享

SpringBoot实现Session缓存共享

对于权限管理和安全认证,我们首先想到的是Spring Security和Apache Shiro,这两者均能实现用户身份认证和复杂的权限管理功能。但是如果我们只是想实现身份认证(如是否登录、会话是否超时),使用session管理即可满足。

spring-session

HttpSession的实现被Spring Session替换,操作HttpSession等同于操作redis中的数据。

目的:保证不同的web站点能够共享同一份Session数据。

在传统单机web应用中,对于一个浏览器发出的多次请求,WEB服务器则通过这个Sessionid来区分请求。一般使用tomcat等web容器时,用户的session是由单台服务器容器管理。浏览器使用cookie记录sessionId,容器根据sessionId判断用户是否存在会话session。

但是网站主键演变,分布式应用和集群是趋势(提高性能)。此时用户的请求可能被负载分发至不同的服务器,此时传统的web容器管理用户会话session的方式即行不通。除非集群或者分布式web应用能够共享session,尽管tomcat等支持这样做。但是这样存在以下两点问题:
1.需要侵入web容器,提高问题的复杂;
2.web容器之间共享session,集群机器之间势必要交互耦合。
基于这些,必须提供新的可靠的集群分布式/集群session的解决方案,突破traditional-session单机限制(即web容器session方式),spring-session应用而生。

spring-session与session是如何做到无缝切换的

1.自定义个Filter,实现doFilter方法
2.继承 HttpServletRequestWrapper 、HttpServletResponseWrapper 类,重写getSession等相关方法(在这些方法里调用相关的 session存储容器操作类)。
3.在 第一步的doFilter中,new 第二步 自定义的request和response的类。并把它们分别传递到过滤器链。
4.把该filter配置到过滤器链的第一个位置上。

引入依赖

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</artifactId>
		</dependency>

启动类添加注解配置

@EnableRedisHttpSession
@SpringBootApplication
public class App {
	public static void main(String[] args)
	{
		SpringApplication.run(App.class, args);
	}
}

Controller

@RestController
public class UserController {
	@RequestMapping(value = "/getSesson")
	public List<String> getSesson(HttpSession session, String name)
	{
		System.out.println(req.getRemoteAddr());
		System.out.println(req.getRemoteHost()+":"+req.getRemotePort());
		String sessionID = req.getSession().getId();
		System.out.println("SessionID-----" + sessionID);
		//
		session.setAttribute("name", "lyndon-8088");
		String testKey = (String)req.getSession().getAttribute("name");
		System.out.println("testKey-----" + testKey);
		//
		List<String> list = new ArrayList<>();
		list.add("testKey= " + testKey);
		list.add("SessionID= " + sessionID);
		list.add("RemoteAddr= " + req.getRemoteAddr());
		list.add("RemoteHost+Port= " + req.getRemoteHost() + ":" + req.getRemotePort());
		return list;
	}
}

Redis查询

[root@localhost ~]# redis-cli -c -h 192.168.236.128 -p 6380 -a 123456
192.168.236.128:6380> keys *
1) "spring:session:sessions:d8eab967-5010-492c-88c8-c049c501909d"
2) "spring:session:expirations:1568471520000"
3) "spring:session:sessions:expires:d8eab967-5010-492c-88c8-c049c501909d"

部署到Nginx配置

start nginx

在这里插入图片描述

测试

在同一个浏览器下访问nginx下的服务 http://localhost:8001/getSession

多次请求后,结果返回了不同服务端下的相同Session数据

[“RemoteAddr= 127.0.0.1”,“RemoteHost+Port= 127.0.0.1:63518”,“SessionID= 8f6da055-6723-400e-b019-89a349d6b383”,“testKey= Server-8088”]

[“RemoteAddr= 127.0.0.1”,“RemoteHost+Port= 127.0.0.1:63499”,“SessionID= 8f6da055-6723-400e-b019-89a349d6b383”,“testKey= Server-8087”]

(完)

参考资料

nginx+springboot+redis 负载均衡Session共享的实现
https://www.jianshu.com/p/e2106832f76b

spring-session(一)揭秘
https://www.cnblogs.com/lxyit/p/9672097.html

spring-session负载均衡原理分析
https://www.jianshu.com/p/beaf18704c3c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值