Tomcat Session简介及绑定&&复制

Session简介。
      应用服务器(Tomcat) 的高可用负载均衡架构设计主要服务于服务无状态这一特性(静态页面),但是事实上,绝大多数生产业务总是有状态的,例如:交易类的电子商务网站,需要有购物车记录用户的购买信息,每次购买请求都是向购物车中增加新的商品;社交网站中,需要记录用户当前的登录状态,获取用户的个人信息、最新发布的消息及好友请求状态等,用户每次刷新页面都需要更新这些信息。
      Session是由应用服务器维持的一个服务器端的存储空间(内存中),用户在连接服务器时,会由服务器生成一个唯一 的SessionID,客户端使用该Session ID为标识符来存取服务器端的Session存储空间。而Session ID则保存到客户端,使用浏览器Cookie保存的,用户提交页面请求时,也会将Session ID提交到服务器端,来存取Session空间的数据。服务器也通过URL重写的方式来传递Session ID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。
      WEB应用中将这些多次请求修改使用的上下文对象称作会话(Session),单机情况下,Session可由部署在服务器上的WEB容器(Tomcat、 Resin) 进行管理。但在使用高可用负载均衡的集群环境中,由于负载均衡服务器可能会将每次请求分发到集任何一台应用服务器(Tomcat).上,所以保证每次请求依然能够获得正确的Session比在单机上实现要复杂的多。
解决方案一:Session绑定

    Session绑定可以利用负载均衡的源地址Hash (ip hash) 算法实现。负载均衡服务器总是将来源于同一个IP的请求分发到同一台服务器上,也可以根据Cookie信息将同一个用户的请求总是分发到同一台服务器上。当然这时负载均衡服务器必须工作在HTTP协议层,上。这样整个会话期间,用户所有的请求都在同一台服务器上处理,即Session 绑定在某台特定服务器上,保证Session总能在这台服务器上获取。这种方法又被称为会话黏滞。

    但是Session绑定的方案显然不符合我们对系统高可用的需求,因为一旦某台服务器宕机,那么该机器上的Session也就不复存在了,用户请求切换到其他机器后因为没有Session而无法完成业务处理。因此虽然大部分负载均衡服务器都能提供源地址负载均衡算法,但很少用网站利用这个算法进行Session管理

解决方案二:Session复制

    Session复制是小型架构使用较多的一种服务器集群Session 管理机制。应用服务器开启Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象,使每台服务器上都保存了所有用户的Session信息,这样任何一台机器右机都不会导致Session数据的丢失,而服务器使用Session时,也只需要在本机获取即可。

    这种方案实现简单,从本机读取Session信息也很快速,但只能应用在集群规模比较小的环境下。当集群规模较大时,集群服务器间需要大量的通信进行Session复制,占用服务器和网络的大量资源,系统不堪负担。而且由于所有用户的Session信息在每台服务器上都有备份,在大量用户访问的情况下,甚至会出现服务器内存不够Session使用的情况。

解决方案三:Session服务器之Memcached

解决方案四:Session服务器之Redis

步骤:配置各个机器的主机名

配置主机名与IP映射

关闭防火墙和selinux

修改Tomcat的两个文件(一共更改三个地方)

启动服务(如果服务起不来主要是网络原因,要声明一下组播地址)

route add -net 224.0.0.0  netmask 240.0.0.0 dev ens......

安装前准备配置:

[root@localhost ~]# vim /etc/hosts

192.168.200.111 nginx
192.168.200.112 node1
192.168.200.113 node2

[root@localhost ~]# scp /etc/hosts 192.168.200.112:/etc/

[root@localhost ~]# scp /etc/hosts 192.168.200.113:/etc/

关闭防火墙及安全机制:

[root@localhost ~]# iptables -F
[root@localhost ~]# systemctl stop firewalld
[root@localhost ~]# setenforce 0

一、解决方案一:Session绑定

1、修改第一台nginx

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf

upstream tomcat_pool {
server 192.168.200.112:8080 weight=1 max_fails=1 fail_timeout=10s;
server 192.168.200.113:8080 weight=1 max_fails=1 fail_timeout=10s;

location / {
root html;
index index.html index.htm;
proxy_pass http://tomcat_server;
proxy_set_header Host $http_host;
}

[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# killall -HUP nginx

网页访问192.168.200.111:

 

 2、修改二、三台虚拟机

[root@node2 ~]# vim /usr/local/tomcat8/webapps/ROOT/session.jsp        //添加以下内容

Session ID:<%= session.getId() %><BR>
SessionPort:<%= request.getServerPort() %>
<% out.println("This tomcat server 192.168.200.112/113");%>

[root@node1 ~]# /usr/local/tomcat8/bin/shutdown.sh

[root@node1 ~]# /usr/local/tomcat8/bin/startup.sh 

 

 因为配置默认是轮询,所以虚拟机不固定。

若在nginx虚拟机的主配置文件中添加 ip_hash;则就不会发生变动。以上方案在企业中用不来

二、解决方案二:Session复制

Tomcat支持Session集群,可在各Tomcat服务器间复制全部session信息,当后端一台Tomcat服务器宕机后,Nginx重新调度用户请求分配到另外一台服务器,客户端可从另一台Tomcat服务上获取用户的session信息。
Session集群可在Tomcat服务器规模(般10台以下)不大时使用,否则会导致Session复制时性能代价过高;

1、[root@node1 ~]# vim /usr/local/tomcat8/conf/server.xml

110行左右:<!-- <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">   -->

下面的有一行注释去掉:<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

[root@node1 ~]# vim /usr/local/tomcat8/webapps/ROOT/WEB-INF/web.xml

倒数第二行添加:<distributable/>

[root@node1 ~]# /usr/local/tomcat8/bin/shutdown.sh &&/usr/local/tomcat8/bin/startup.sh 

[root@node1 ~]# netstat -lnpt | grep -E "8080|4000"
tcp6 0 0 :::8080 :::* LISTEN 36753/java
tcp6 0 0 192.168.200.112:4000 :::* LISTEN 36753/java

去网页上测试,session IP不变,node和IP号随意变更

 

原文地址:https://www.cnblogs.com/990624lty-jhc/p/11579203.html