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) 算法实现。将用户与服务器绑定,用户的所有请求全部由一台服务器处理。当然这时负载均衡服务器必须工作在HTTP 协议层上。
缺点:但是Session绑定的方案显然不符合我们对系统高可用的需求,因为一旦某台服务器宕机,那么该机器上的Session也就不复存在了,用户请求切换到其他机器后因为没有Session
而无法完成业务处理。所有很少使用。
===================================================
解决方案二: Session 复制
Session复制是小型架构使用较多的一种服务器集群Session管理机制。应用服务器开启
Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象,使每台服务
器上都保存了所有用户的Session信息,这样任何一台机器宕机都不会导致Session数据的丢
失,而服务器使用Session时,也只需要在本机获取即可。
缺点:这种方案实现简单,从本机读取Session信息也很快速,但只能应用在集群规模比较小的环境下。当集群规模较大时,集群服务器间需要大量的通信进行Session复制,占用服务器和网络的大量资源,系统不堪负担。而且由于所有用户的Session信息在每台服务器上都有备份,在大量用户访问的情况下,甚至会出现服务器内存不够Session使用的情况。
Session集群可在Tomcat服务器规模(-般10台以下)不大时使用,否则会导致Session
复制时性能代价过高;
默认端口:4000
====================================================
解决方案三: Session服务器之Memcached
====================================================
解决方案四: Session服务器之Redis
Redis与MenIcached的区别
内存利用率:使用简单的key-value (键值对)存储的话,Memcached 的内存利用率更高,而如果Redis采用hash结构来做key-value 存储,由于其组合式的压缩,其内存利用率会高于Memcached。
性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中, Memcached性能要高于Redis, 虽然Redis. 最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis支持数据的备份,即master-slave模式的数据备份。。
Redis不仅仅支持简单的key-Value类型的数据,同时还提供list, set, zset, hash 等数据结构的存储。
默认端口6379
====================================================
实验环境:
【1】操作系统centos7.5:主机192.168.200.66  主机名nginx  软件包列表nginx
【2】操作系统centos7.5:主机192.168.200.67  主机名node1 软件包列tomcat
【3】操作系统centos7.5:主机192.168.200.68  主机名node2  软件包列表tomcat
环境配置:
=================
nginx66主机
[root@nginx ~]# vim /etc/hosts
192.168.200.66 nginx
192.168.200.67 node1
192.168.200.68 node2
保存退出
[root@nginx ~]# scp /etc/hosts 192.168.200.67:/etc/
The authenticity of host '192.168.200.67 (192.168.200.67)' can't be established.
ECDSA key fingerprint is SHA256:BHiaAGVjdmSxIi8neERFseec7NLTOxX1+vkOQY88dxg.
ECDSA key fingerprint is MD5:83:c6:95:a4:f7:58:76:29:37:16:2b:57:c0:43:af:5b.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': yes
Warning: Permanently added '192.168.200.67' (ECDSA) to the list of known hosts.
root@192.168.200.67's password:
hosts               100%  222    86.3KB/s   00:00
[root@nginx ~]# scp /etc/hosts 192.168.200.68:/etc/
The authenticity of host '192.168.200.68 (192.168.200.68)' can't be established.
ECDSA key fingerprint is SHA256:nOug2TzzVJZysB+hBvgEnxvaOESr6XmI28kFoJIbfVc.
ECDSA key fingerprint is MD5:80:57:a3:0f:10:58:25:d9:94:4b:e8:ef:31:94:c8:9f.
Are you sure you want to continue connecting (yes/no)? yes 
Warning: Permanently added '192.168.200.68' (ECDSA) to the list of known hosts.
root@192.168.200.68's password:
hosts               100%  222   142.8KB/s   00:00
选择xshell的全部会话,然后输入以下命令
关闭防火墙安全机制
[root@nginx ~]# iptables -F
[root@nginx ~]# setenforce 0
[root@nginx ~]# systemctl stop firewalld
[root@localhost ~]# hostname nginx
[root@localhost ~]# bash
[root@nginx ~]#
安装nginx:
 32     upstream tomcat_pool{
 33
 34         server 192.168.200.67:8080 weight=1 max_fails=1 fail_timeout=10s;
 35         server 192.168.200.68:8080 weight=1 max_fails=1 fail_timeout=10s;
 36         }     //做轮询
 47         location / {
 48             root   html;
 49             index  index.html index.htm;
 50             proxy_pass   http://tomcat_pool;    #做反向代理,用于测试,可以访问另外两台主机的页面。
 51             proxy_set_header Host $http_host;      
 }
保存退出
[root@nginx ~]# nginx -t
[root@nginx ~]# killall -HUP nginx
在浏览器中进行访问
=============
主机node1 67
[root@localhost ~]# hostname node1
[root@localhost ~]# bash
[root@node1 ~]# vim /usr/local/tomcat8/webapps/ROOT/session.jsp
Session ID:<%= session.getId() %><BR>    #id号
SessionPort:<%= request.getServerPort() %>#端口号  自动输出
<% out.println("This tomcat server 192.168.200.67");%>
保存退出
重启tomcat
访问192.168.200.67:8080/session.jsp
=============
主机node2 68
[root@client ~]# hostname node2
[root@client ~]# bash
[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.68");%>
保存退出
重启tomcat
访问192.168.200.68:8080/session.jsp
=-----访问192.168.200.66/session.jsp  出现页面轮询
nginx主机66
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
    upstream tomcat_pool{
        ip_hash;
        server 192.168.200.67:8080 weight=1 max_fails=1 fail_timeout=10s;
        server 192.168.200.68:8080 weight=1 max_fails=1 fail_timeout=10s;
        }
保存退出(加一个ip_hash)
[root@nginx ~]# killall -HUP nginx
绑定IP后会发现如果一个服务器瘫痪了,用户的信息就没有了。(这里可以把一个服务器关闭做测试)
所以这种方式不好用企业也不用
================================================
session复制
tomcat支持session集群,可以在各个tomcat服务器间复制全部session信息,当后端一台tomcat服务器宕(dang)机后,
nginx重新调度用户请求分配到另外一台服务器,客户端可从另一台tomcat服务器上获取用户的session信息
session集群可在tomcat服务器规模(一般10台以下)不大使用,否则会导致session复制时性能代价过高。
注意:
这个实验:
【1】配置各个机器的主机名
【2】配置主机名和IP的映射
【3】关闭防火墙和selinux
======
主机67node1
[root@node1 ~]# vim /usr/local/tomcat8/conf/server.xml
128     <Engine name="Catalina" defaultHost="localhost" jvmRoute="node1">  #引擎
134       <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>  #去掉注释
保存退出
[root@node1 ~]# vim /usr/local/tomcat8/webapps/ROOT/WEB-INF/web.xml
  在倒数第二行添加:<distributable/>
保存退出
重启tomcat
[root@node1 ~]# netstat -lnpt | grep -E "8080|4000"  #4000端口必须打开才能进行复制
tcp6       0      0 :::8080                 :::*                    LISTEN      41910/java         
tcp6       0      0 192.168.200.67:4000     :::*                    LISTEN      41910/java 
======
主机68node2
[root@node2 ~]# vim /usr/local/tomcat8/conf/server.xml
128     <Engine name="Catalina" defaultHost="localhost" jvmRoute="node2">
134       <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>  #去掉注释
保存退出
[root@node2 ~]# vim /usr/local/tomcat8/webapps/ROOT/WEB-INF/web.xml
  在倒数第二行添加:<distributable/>
保存退出
重启tomcat
[root@node2 ~]# grep "4000" /usr/local/tomcat8/logs/catalina.out   ##4000端口必须打开才能进行复制
================
去掉nginx配置文件中的ip_hash
在浏览器中进行访问 192.168.200.66/session.jsp
看sessionID,它是不会变的这样就实现了session的复制
注意:这种方式有可能会导致有一个tomcat服务起不来,所以要添加session的组播地址
(一般都是因为网络的原因)
在tomcat机器上都输入以下命令
[root@node1 ~]# route add -net 244.0.0.0 netmask 240.0.0.0 devens32
[root@node2 ~]# route add -net 244.0.0.0 netmask 240.0.0.0 devens32
===========================================
第二种做法是tomcat有官方的文档
它不用去掉以下内容的注释而是在这个内容下面添加官方的tomcat session复制的有关文档,
但是要修改它所对应的IP ,这种做法对于session复制更加可靠
<!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>-->
==========================================
方案三:
session 服务器之Memcached  (也叫做session的共享 session的独立服务器)
                  (内存型的缓存服务)
Memcached选项
-h #查看帮助信息。
-P #指定memcached监听的端口号默认11211
-| #memcached服务器的ip地址
-U #memcached程序运行时使用的用户身份必须是root用户
-m #指定使用本机的多少物理内存存数据默认64M
-C   #memcached服务的最大链接数
-vvv #显示详细信息
-n #chunk size的最小空间是多少单位字节
-f #chunk size大小增长的倍数默认1.25倍
-d #在后台启动
对之前做的配置进行还原,
【1】去掉引擎
【2】加上注释
【3】[root@node2 ~]# vim /usr/local/tomcat8/conf/server.xml
[root@node2 ~]# vim /usr/local/tomcat8/webapps/ROOT/WEB-INF/web.xml
这两个文件进行还原在进行重启。
将两个tomcat又当作memcached
注意memcached-session-manager-tc7-1.5.1.jar 必须与tomcat版本一致才行,这个实验才能成功 ,所以这个做法已经逐渐被取代。
-==========
主机67node1
[root@node1 ~]# yum -y install libevent memcached
[root@node1 ~]# memcached -u root -m 512M -n 10 -f 2 -d -vvv -c 512
[root@node1 ~]# netstat -lnpt |grep :11211   //查看memcached是否开启
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      42426/memcached    
tcp6       0      0 :::11211                :::*                    LISTEN      42426/memcached
测试memcached是否可以缓存数据
安装telnet软件
[root@node1 ~]# yum -y install telnet
[root@node1 ~]# telnet 192.168.200.67 11211
Trying 192.168.200.67...
<30 new auto-negotiating client connection
Connected to 192.168.200.67.
Escape character is '^]'.
set username 0 0 8   # 标识符  过期时间 长度
<30 set username 0 0 8
30: going from conn_parse_cmd to conn_nread
zhangsan
> NOT FOUND username
>30 STORED
30: going from conn_nread to conn_write
30: going from conn_write to conn_new_cmd
30: going from conn_new_cmd to conn_waiting
30: going from conn_waiting to conn_read
STORED
get username
30: going from conn_read to conn_parse_cmd
<30 get username
> FOUND KEY username
>30 sending key username
>30 END
30: going from conn_parse_cmd to conn_mwrite
30: going from conn_mwrite to conn_new_cmd
30: going from conn_new_cmd to conn_waiting
30: going from conn_waiting to conn_read
VALUE username 0 8
zhangsan
END
quit
30: going from conn_read to conn_parse_cmd
<30 quit
30: going from conn_parse_cmd to conn_closing
<30 connection closed.
Connection closed by foreign host.  //测试成功 ,这里用添加一个用户,并能够获取,表示存取成功
---接着让tomcat1 tomcat2 通过(msm)连接到memcached
将session包中的"*.jar复制到/usr/local/tomcat/lib/"下面,包在E:软件安装Linux 软件SessionTomcat7-Memcached JAR包
[root@node1 ~]# mkdir session
[root@node1 ~]# cd session/
[root@node1 session]# rz -E
rz waiting to receive.
[root@node1 session]# ls
javolution-5.5.1.jar
kryo-1.03.jar
kryo-serializers-0.10.jar
memcached-2.5.jar
memcached-session-manager-1.5.1.jar
memcached-session-manager-tc7-1.5.1.jar
minlog-1.2.jar
msm-javolution-serializer-1.5.1.jar
msm-kryo-serializer-1.6.4.jar
reflectasm-0.9.jar
spymemcached-2.7.3.jar
[root@node1 ~]# cp session/*.jar /usr/local/tomcat8/lib/
[root@node1 ~]# vim /usr/local/tomcat8/conf/context.xml
 30 <Manager    className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
 31 memcachedNodes="memA:192.168.200.67:11211 memB:192.168.200.68:11211"
 32 requestUrilgnorePattern=".*(ico|png|gif|jpg|css|js)$"
 33 transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
 34 />
保存退出
重启tomcat
[root@node1 ~]# <30 new auto-negotiating client connection   //自动显示
<31 new auto-negotiating client connection
<32 new auto-negotiating client connection
========
主机68node2
[root@node2 ~]# yum -y install libevent memcached
[root@node2 ~]# memcached -u root -m 512M -n 10 -f 2 -d -vvv -c 512
[root@node2 ~]# netstat -lnpt |grep :11211
tcp        0      0 0.0.0.0:11211           0.0.0.0:*               LISTEN      42426/memcached    
tcp6       0      0 :::11211                :::*                    LISTEN      42426/memcached
[root@node2 ~]# yum -y install telnet
[root@node2 ~]# telnet 192.168.200.68 11211
Trying 192.168.200.68...
<30 new auto-negotiating client connection
Connected to 192.168.200.68.
Escape character is '^]'.
。。。。。。//同样的测试
[root@node2 ~]# mkdir session
[root@node2 ~]# cd session/
[root@node2 session]# rz -E
rz waiting to receive.
[root@node2 session]# ls
javolution-5.5.1.jar
kryo-1.03.jar
kryo-serializers-0.10.jar
memcached-2.5.jar
memcached-session-manager-1.5.1.jar
memcached-session-manager-tc7-1.5.1.jar
minlog-1.2.jar
msm-javolution-serializer-1.5.1.jar
msm-kryo-serializer-1.6.4.jar
reflectasm-0.9.jar
spymemcached-2.7.3.jar
[root@node2 ~]# cp session/*.jar /usr/local/tomcat8/lib/
[root@node2 ~]# vim /usr/local/tomcat8/conf/context.xml
 30 <Manager    className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
 31 memcachedNodes="memA:192.168.200.67:11211 memB:192.168.200.68:11211"
 32 requestUrilgnorePattern=".*(ico|png|gif|jpg|css|js)$"
 33 transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
 34 />
保存退出
重启tomcat
[root@node2 ~]# <30 new auto-negotiating client connection   //自动显示
<31 new auto-negotiating client connection
<32 new auto-negotiating client connection
=================================================
恢复原始
ls session/ |while read line; do rm -rf /usr/local/tomcat/lib/$line; done 
删除拷贝到/usr/local/tomcat/lib/ 下面的包
 
=======================
解决方案四: Session服务器之Redis
Redis与MenIcached的区别
内存利用率:使用简单的key-value (键值对)存储的话,Memcached 的内存利用率更高,而如果Redis采用hash结构来做key-value 存储,由于其组合式的压缩,其内存利用率会高于Memcached。
性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中, Memcached性能要高于Redis, 虽然Redis. 最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis支持数据的备份,即master-slave模式的数据备份。。
Redis不仅仅支持简单的key-Value类型的数据,同时还提供list, set, zset, hash 等数据结构的存储。
默认端口6379
配置方法:
安装redis
[root@node1 ~]# tar xf redis-3.2.5.tar.gz -C /usr/src/
[root@node1 ~]# cd /usr/src/redis-3.2.5/
[root@node1 redis-3.2.5]# make
[root@node1 ~]# mkdir -p /usr/local/redis/{bin,etc,var}
[root@node1 redis]# cd /usr/src/redis-3.2.5/src/
[root@node1 src]# cp redis-benchmark redis-check-rdb redis-check-aof redis-cli redis-server /usr/local/redis/bin/
[root@node1 redis-3.2.5]# cp redis.conf /usr/local/redis/etc/
修改配置文件
[root@node1 redis-3.2.5]# vi /usr/local/redis/etc/redis.conf
bind 127.0.0.1  --》bind 0.0.0.0
daemonize no  --》daemonize yes
启动
[root@node1 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
上传redis jar包
[root@node1 a]# cp * /usr/local/tomcat/lib/
修改配置文件
[root@node1 a]# vi /usr/local/tomcat/conf/context.xml
<Valve
className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />     <ManagerclassName="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.200.112"     redis的ip地址
port="6379"               redis的端口
database="0"              第几个数据库
maxInactiveInterval="60" />
重启tomcat
[root@node1 a]# /usr/local/tomcat/bin/shutdown.sh
[root@node1 a]# /usr/local/tomcat/bin/startup.sh
 
在浏览器中192.168.200.66/session.jsp
会发现页面的ID号是固定的,还有缓存服务器会变化
=================================================
恢复原始
ls session/ |while read line; do rm -rf /usr/local/tomcat/lib/$line; done 
删除拷贝到/usr/local/tomcat/lib/ 下面的包
=======================
解决方案四: Session服务器之Redis  (6379端口)
Redis与MenIcached的区别
内存利用率:使用简单的key-value (键值对)存储的话,Memcached 的内存利用率更高,而如果Redis采用hash结构来做key-value 存储,由于其组合式的压缩,其内存利用率会高于Memcached。
性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中, Memcached性能要高于Redis, 虽然Redis. 最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
Redis支持数据的备份,即master-slave模式的数据备份。。
Redis不仅仅支持简单的key-Value类型的数据,同时还提供list, set, zset, hash 等数据结构的存储。
默认端口6379
配置方法:
在任意一台机器上选node1,在安装时如果发现tcl报错,则安装tcl
安装redis
[root@node1 ~]# tar xf redis-3.2.5.tar.gz -C /usr/src/
[root@node1 ~]# cd /usr/src/redis-3.2.5/
[root@node1 redis-3.2.5]# make
[root@node1 ~]# mkdir -p /usr/local/redis/{bin,etc,var}
[root@node1 redis]# cd /usr/src/redis-3.2.5/src/
[root@node1 src]# cp redis-benchmark redis-check-rdb redis-check-aof redis-cli redis-server /usr/local/redis/bin/
[root@node1 redis-3.2.5]# cp redis.conf /usr/local/redis/etc/
修改配置文件
[root@node1 redis-3.2.5]# vi /usr/local/redis/etc/redis.conf
bind 127.0.0.1  --》bind 0.0.0.0
daemonize no  --》daemonize yes
启动
[root@node1 ~]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf
-----------
67 68 都上传redis的jar包
[root@node1 ~]# mkdir redis-session
[root@node1 ~]# cd  redis-session
[root@node1 redis-session]# rz -E
rz waiting to receive.
[root@node1 redis-session]# cp *.jar /usr/local/tomcat8/lib/
修改配置文件
[root@node1 ~]# vim /usr/local/tomcat8/conf/context.xml
<Valve
className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />    
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.200.67"     redis的ip地址
port="6379"               redis的端口
database="0"              第几个数据库
maxInactiveInterval="60" />
重启tomcat
[root@node1 a]# /usr/local/tomcat/bin/shutdown.sh
[root@node1 a]# /usr/local/tomcat/bin/startup.sh
---
68主机
[root@node2 ~]# mkdir redis-session
[root@node2 ~]# cd  redis-session
[root@node2 redis-session]# rz -E
rz waiting to receive.
[root@node2 redis-session]# cp *.jar /usr/local/tomcat8/lib/
[root@node2 ~]# vim /usr/local/tomcat8/conf/context.xml
<Valve
className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />    
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
host="192.168.200.67"     redis的ip地址
port="6379"               redis的端口
database="0"              第几个数据库
maxInactiveInterval="60" />
保存退出
重启tomcat
在浏览器中192.168.200.66/session.jsp
会发现IP发生变化,但是sessionID 不变
!!!!!!!!!!!!!!!!完成!!!
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/elin989898/p/11933416.html