同域名下相同项目(集群环境)实现Session共享
在同一个域名下,比如:www.p2p.com
同一个项目,部署了多台tomcat,这就是典型的集群。我们的入门案例就属于这种应用场景,只不过在实际开发的过程中,我们如果存在了tomcat集群,那么肯定会使用nginx进行负载均衡,那么这种情况下我们该如何处理。
我们将上一个阶段的p2p项目实现集群部署下的Session共享,因为我们只是演示Session共享,所以我们试用一个简易版本的p2p,在我给大家提供的资料中,该p2p中只包含p2p和dataservice,在Linux服务器上,我们准备三台tomcat,其中两台部署p2p,并实现session共享,另一台部署dataservice。
① 使用Xftp将p2p上传到tomcat9100和9200的webapps目录下
② 使用Xftp将dataservice上传到tomcat9300的webapps目录下
③ 使用资源下的SQL脚本,重新创建数据库的表
因为目前这个p2p的项目表结构和上一个阶段的稍微有些区别,所以我们这里更新一下:
A、 启动mysql数据库
B、 通过MySQL客户端工具Navivat创建新的库
C、 指定数据库名字为p2p2,字符集编码为utf-8
D、 新建查询,执行p2p-data.sql脚本
E、 执行成功后,表结构如下
④ 通过Xftp工具连接Linux,修改tomcat9300下的dataservice的连接信息
A、 使用记事本打开,修改redis.properties,保存
B、 修改datasource.properties,保存
C、 修改applicationContext-dubbo-provide.xml注册中心的地址,并保存
⑤ 通过Xftp工具连接Linux,修改tomcat9100下的p2p的连接信息
这里只需要修改applicationContext-dubbo-consumer.xml文件中zk注册中心的地址即可。
⑥ 通过Xftp工具连接Linux,修改tomcat9200下的p2p的连接信息
这里只需要修改applicationContext-dubbo-consumer.xml文件中zk注册中心的地址即可。
⑦ 确保Linux系统上的各应用服务器启动
注意:先通过ps –ef | grep XXX命令查看,如果已经启动,就不需要再启动了。
A、 启动ZooKeeper服务器
B、 启动MySQL服务器
C、 启动Redis服务器
D、 启动tomcat9300服务器(为了避免出错先关闭,再启动)
E、 启动tomcat9100服务器(为了避免出错先关闭,再启动)
F、 启动tomcat9200服务器(为了避免出错先关闭,再启动)
G、 直接访问tomcat的方式,在浏览器输入地址访问tomcat9100和tomcat9200
⑧ 使用Nginx对tomcat9100和tomcat9200进行负载均衡
A、 负载均衡的配置,这里使用的是轮询策略
upstream www.p2p.com{
server 127.0.0.1:9100;
server 127.0.0.1:9200;
}
B、location匹配的配置,注意:这里对静态资源的处理,我们暂时先注释掉
location /p2p{
proxy_pass http://www.p2p.com;
}
如果要是实现了静态代理,别忘了启动所有的nginx服务器(负载|代理)
C、 重启Nginx
D、 在浏览器中输入地址,直接访问Nginx服务器,实现负载均衡
⑨ Nginx对集群负载均衡之后,登录不成功,但是直接访问tomcat9100或者tomcat9200都是可以成功登录的(Session丢失),分析原因:
因为默认我们负载均衡使用的是轮询策略,每次发送请求给nginx服务器,都会切换tomcat服务器,这个时候没有使用任何session共享策略,所以登录不成功。
⑩ Nginx对集群负载均衡之后,Session共享方案
A、 修改nginx.conf配置文件,将轮询策略修改为ip_hash
但是这种情况,一旦ip发生变化,或者某台服务器出现故障,会重新分配,不稳定;
所以我们看下这种情况后,将ip_hash注释掉。
B、 使用SpringSession
使用Spring Session实现session共享,我们不需要修改代码,只要修改一些配置文件即可,为了演示方便,我们直接使用Xftp修改已经发布到tomcat上的项目;
向tomcat9100和tomcat9200的p2p项目中加jar包,这个jar包我已经准备好了。
修改tomcat9100和tomcat9200的p2p项目的web.xml配置文件,添加Spring Session过滤器,因为我们项目本身已经通过springMVC启动了容器,所以spring监听器不需要加了,直接从01-springsession-web中拷贝即可;
将01-springsession-web项目中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共享。
在同一个域名下,有多个不同的项目(项目的上下文根不一样)比如:
www.web.com/p2p
www.web.com/shop
如图:
在01-springsession-web项目的基础上,将本地tomcat9100的上下文根修改为p2p,将本地tomcat92
① 打开Edit Configurations进行配置
② 在Deployment选项卡下,设置本地tomcat9100的Application context为/p2p
③ 在Deployment选项卡下,设置本地tomcat9200的Application context为/shop
④ 在idea中重新启动本地的两台tomcat服务器
⑤ 在浏览器中访问tomcat9100(p2p),设置session
⑥ 在浏览器中访问tomcat9200(shop),获取session
⑦ 分析Session共享失败原因
我们通过浏览器提供的开发人员工具可以发现,这两个请求的cookie的路径(path)不一致,虽然我们已经加了Spring Session共享机制,但是后台服务器认为这是两个不同的会话(session),可以通过Redis客户端工具(Redis Destop Mananger)查看,先清空,然后访问,发现是维护了两个不同的session,所以不能实现共享。
⑧ 解决方案 设置Cookie路径为根/上下文
在applicationContext-session.xml文件中,加如下配置:
⑨ 在idea中重新启动本地的两台tomcat服务器
⑩ 在浏览器中访问tomcat9100(p2p),设置session
⑪ 在浏览器中访问tomcat9200(shop),获取session
注意:测试的时候要先清空浏览器缓存。
同一个根域名,不同的二级子域名
比如:
www.web.com
beijing.web.com
nanjing.web.com
如图:
• 设置Cookie路径为根/上下文,项目名一样的话,此步骤可以省略
• 设置cookie的域名为根域名 web.com
在01-springsession-web项目的基础上,将本地tomcat9100的上下文根修改为p2p,将本地tomcat9200的上下文根修改为shop;在本机host文件中修改127.0.0.1的映射关系模拟不同的域名访问。
① 延续上面的案例的配置,两台本地tomcat服务器9100和9200,上下文根分别是p2p和shop
② 修改本地hosts文件,加入如下配置
③ 在idea中重新启动本地的两台tomcat服务器
④ 在浏览器中访问tomcat9100(p2p),设置session
注意,这里不再使用localhost访问,而是使用我们映射的域名
⑤ 在浏览器中访问tomcat9200(shop),获取session
注意,这里也不再使用localhost访问,而是使用我们映射的域名
⑥ 分析Session共享失败原因
我们通过浏览器提供的开发人员工具可以发现,虽然这两个cookie的路径(path)都设置为了“/”,但是这两个cookie的域名不一致,虽然我们已经加了Spring Session共享机制,但是后台服务器同样认为这是两个不同的会话(session),可以通过Redis客户端工具(Redis Destop Mananger)查看,先清空,然后访问,发现是维护了两个不同的session,所以不能实现共享,也就是说后台区分是否同一个session和路径和域名有关。
⑦ 解决方案 设置Cook ie的域名为根域名 web.com
在applicationContext-session.xml文件中,加如下配置:
注意:域名要和hosts文件中配置的域名后面一样
⑧ 在idea中重新启动本地的两台tomcat服务器
⑨ 在浏览器中访问tomcat9100(p2p),设置session
⑩ 在浏览器中访问tomcat9200(shop),获取session
注意:清空浏览器缓存