大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全家桶1年46,售后保障稳定
目录
一、同域名下相同项目(集群环境)实现 Session 共享
在同一个域名下,比如:www.p2p.com
同一个项目,部署了多台 tomcat,这就是典型的集群。我们上一篇文章的入门案例就属于这种应用场景,只不过在实际开发的过程中,我们如果存在了 tomcat 集群,那么肯定会使用 nginx 进行负载均衡,那么这种情况下我们该如何处理。
1. 思路
我们将上一个阶段的 p2p 项目实现集群部署下的 Session 共享,该 p2p 中只包含 p2p 和dataservice 两个模块项目,在 Linux 服务器上,我们准备三台 tomcat,其中两台部署p2p,并实现 session 共享,另一台部署 dataservice。
2. 架构图
3. 实现步骤
使用 Xftp 将 p2p 上传到 tomcat 9100 和 9200 的 webapps 目录下
使用 Xftp 将 dataservice 上传到 tomcat9300 的 webapps 目录下
使用资源下的SQL脚本,创建数据库的表
A、启动 mysql 数据库
D、通过MySQL客户端工具 Navivat 创建新的库
通过 Xftp 工具连接 Linux,修改 tomcat 9300 下的 dataservice 的连接信息
A、使用记事本打开,修改 redis.properties,保存。
B、修改 datasource.properties,保存
C、修改 applicationContext-dubbo-provider.xml 注册中心的地址,并保存
通过 Xftp 工具连接 Linux,修改tomcat 9100下的 p2p 的连接信息
这里只需要修改 applicationContext-dubbo-consumer.xml文件中zk注册中心的地址即可
通过 Xftp 工具连接 Linux,修改 tomcat 9200 下的 p2p 的连接信息
这里只需要修改 applicationContext-dubbo-consumer.xml 文件中zk注册中心的地址即可
确保Linux系统上的各应用服务器启动
A、启动 ZooKeeper 服务器
B、启动 mysql 服务器
C、启动 Redis 服务器
按顺序启动 tomcat9300 —> tomcat9100 —-> tomcat9200 服务器
直接访问 tomcat 的方式,在浏览器输入地址访问 tomcat 9100 和 tomcat 9200,可以直接看到网站。
使用Nginx对 tomcat9100 和 tomcat9200 进行负载均衡
A、负载均衡的配置,这里使用的是轮询策略
B、location匹配的配置,注意:这里对静态资源的处理,我们暂时先注释掉
如果要是实现了静态代理,别忘了启动所有的nginx服务器 (负载|代理)
C、启动 Nginx
D、在浏览器中输入地址,直接访问 Nginx 服务器,实现负载均衡
Session 丢失
Nginx对集群负载均衡之后,登录不成功,但是直接访问 tomcat9100 或者 tomcat9200 都是
可以成功登录的。
分析原因
因为默认我们负载均衡使用的是轮询策略,每次发送请求给nginx服务器,都会切换tomcat 服务器,这个时候没有使用任何 session 共享策略,所以登录不成功
Nginx对集群负载均衡之后,Session共享方案
A、修改 nginx.conf 配置文件,将轮询策略修改为 ip_hash
但是这种情况,一旦 ip 发生变化,或者某台服务器出现故障,会重新分配,不稳定,所以我们舍弃这种情况,将ip_hash注释掉
B、使用 SpringSession
使用 Spring Session 实现 session 共享,我们不需要修改代码,只要修改一些配置文件即可,为了演示方便,我们直接使用 Xftp 修改已经发布到 tomcat 上的项目
向 tomcat 9100 和 tomcat 9200 的 p2p 项目中加 jar 包
修改 tomcat9100 和 tomcat9200 的 p2p 项目的 web.xml 配置文件,添加 Spring Session 过滤器,因为我们项目本身已经通过 springMVC 启动了容器,所以 spring 监听器不需要加了,直接从入门案例中拷贝即可。
将上一篇文章入门案例项目中 resources 下的 applicationContext-session.xml 和redis.properties 拷贝到 tomcat9100 和 tomcat9200 的 p2p 项目 WEB-INF/classes 下
修改 tomcat9100 和 tomcat9200 的 p2p 项目 WEB-INF/classes 下的applicationContext.xml 文件,引入 applicationContext-session.xml
重启三台tomcat服务器,浏览器访问进行登录测试,可以实现Session共享。
二、同域名下不同项目实现 Session 共享
在同一个域名下,有多个不同的项目 (项目的上下文根不一样) 比如:
www.web.com/p2p
www.web.com/shop
如图:
1. 解决方案
设置 Cookie 路径为根/上下文
2. 案例设计思路
在上篇文章的入门项目 springsession-web项目 的基础上,将本地 tomcat9100 的上下文根修改为 p2p,将本地 tomcat9200 的上下文根修改为 shop
3. 实现步骤
打开 Edit Configurations
在 Deployment 选项卡下,设置本地 tomcat9100 的 Application context 为 /p2p
在 Deployment 选项卡下,设置本地 tomcat9200 的 Application context 为 /shop
在 idea 中重新启动本地的两台 tomcat 服务器
在浏览器中访问 tomcat 9100 (p2p) ,设置 session
在浏览器中访问 tomcat 9200 (shop) ,获取 session
我们发现无法获取 session
分析 Session 共享失败原因
我们通过浏览器提供的开发人员工具可以发现,这两个请求的 cookie 的路径 (path) 不一致,虽然我们已经加了 Spring Session 共享机制,但是后台服务器认为这是两个不同的会话 (session),可以通过Redis客户端工具 (Redis Destop Mananger) 查看,先清空,然后访问,发现是维护了两个不同的 session,所以不能实现共享。
设置 Cookie 路径为根/上下文
在 applicationContext-session.xml 文件中,加如下配置:
<!-- Spring session 的配置类 -->
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="cookieSerializer" ref="defaultCookieSerializer"></property>
</bean>
<!--设置cookie的存放方式具体实现-->
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookiePath" value="/"></property>
</bean>
重启两台 tomcat 服务器,重新执行上面的流程,这次我们可以获取到session
注意 :测试的时候要先清空浏览器缓存。
三、同根域名不同二级子域名下的项目实现 Session 共享
同一个根域名,不同的二级子域名
比如:
www.web.com
beijing.web.com
nanjing.web.com
如图:
1. 做法
- 设置 Cookie 路径为根 / 上下文,项目名一样的话,此步骤可以省略
- 设置 Cookie 的域名为根域名 web.com
2. 案例设计思路
在 springsession-web项目的基础上,将本地 tomcat9100 的上下文根修改为 p2p,将本地tomcat9200的上下文根修改为shop,在本机host文件中修改127.0.0.1的映射关系模拟不同的域名访问
3. 实现步骤
延续上面的案例的配置,两台本地 tomcat 服务器 9100 和 9200,上下文根分别是 p2p 和shop,上面我们已经配置好了。
修改本地 hosts 文件,加入如下配置。
在 idea 中重新启动本地的两台tomcat服务器,按上面的流程再setSession和getSession
在浏览器中访问 tomcat 9200 (shop) ,获取 session
session 再次获取失败
分析Session共享失败原因
我们通过浏览器提供的开发人员工具可以发现,虽然这两个 cookie 的路径 (path) 都设置为了“/”,但是这两个 cookie 的域名不一致,虽然我们已经加了 Spring Session 共享机制,但是后台服务器同样认为这是两个不同的会话 (session),可以通过Redis客户端工具(Redis Destop Mananger)查看,先清空,然后访问,发现是维护了两个不同的session,所以不能实现共享,也就是说后台区分是否同一个session和路径和域名有关。
解决方案 :设置 Cookie 的域名为根域名 web.com
在 applicationContext-session.xml 文件中,修改成如下配置:
注意: 域名要和hosts文件中配置的域名后面一样
<bean id="defaultCookieSerializer" class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookiePath" value="/"></property>
<property name="domainName" value="web.com"></property>
</bean>
同样,再次重启两台 tomcat 服务器,重新执行上面的流程,这次我们可以获取到session。
注意 :测试的时候要先清空浏览器缓存。
四、单点登录
不同根域名下的项目实现Session共享,比如阿里巴巴这样的公司,有多个业务线,多个网站,用户在一个网站登录,那么其他网站也会是登录了的状态,比如:登录了淘宝网,则天猫网也是登录的。
www.taobao.com
www.tmall.com
比如:
www.web.com
www.p2p.com
www.dai.com
这三个根域名不同
对于不同根域名的场景,要实现一处登录,处处登录,Spring Session不支持
单点登录(Single Sign On),简称为 SSO,是流行的企业业务整合的解决方案之一,SSO是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
要实现单点登录,我们需要单独写一个 SSO 系统。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234369.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...