Tomcat之session解决方案

栏目: Java · 发布时间: 7年前

内容简介:用户访问服务器资源主要分成两类,一类是无状态访问,例如请求一张图片。另一类是有状态访问,这种情况下,服务器需要记录追踪用户状态,并根据用户所处状态做出不同响应,典型的例子是购物车。Session的作用就是在Web服务器上保持用户的状态信息。用户请求连接服务器时,服务器会生成一个唯一的sessionID为标识符至用户端本地,客户端使用该sessionID来存/取服务器端的session空间。sessionID是客户端浏览器cookie保存的。当客户端访问Tomcat集群时,所有的请求将被Nginx拦截,由Ng

session方案及配置

用户访问服务器资源主要分成两类,一类是无状态访问,例如请求一张图片。另一类是有状态访问,这种情况下,服务器需要记录追踪用户状态,并根据用户所处状态做出不同响应,典型的例子是购物车。Session的作用就是在Web服务器上保持用户的状态信息。

用户请求连接服务器时,服务器会生成一个唯一的sessionID为标识符至用户端本地,客户端使用该sessionID来存/取服务器端的session空间。sessionID是客户端浏览器cookie保存的。

当客户端访问Tomcat集群时,所有的请求将被Nginx拦截,由Nginx做负载均衡后转发给后台真实Tomcat。按照这个流程就可能出现一个问题,当用户进行页面刷新或跳转时,每次请求将被转发给不同的Tomcat处理,这样就会造成Session的不同步。举个简单的栗子,例如当用户往购物车添加商品时,兴高采烈地准备买单了,当他跳转到付款页面却发现购物车被清空了,这就是Session丢失的典型栗子。因此,我们需要为集群环境做Session同步。

单机环境下,session可有部署在服务器上的web容器如:Tomcat进行保存管理。但在使用负载均衡集群时如架构前端Nginx来负载均衡后端多台Tomcat,所以可能分发到任何一台后端的Tomcat;虽然呢,也有类似于Nginx中的ip_hash算法可以将客户端和服务器做一个绑定,但是弊端太多,生产环境慎用。

下面将介绍几种session的方案

一、session绑定

session绑定就是利用负载均衡服务器的hash源IP地址算法实现,将来源于同一个IP的请求总是分发到同一台后端web服务器上,又称为会话粘滞。 但是如果该服务器死机或故障,那该用户的session空间也就不复存在了,就如我们网页浏览购物网站时,刚添加到购物车的宝贝,一刷新全没了,用户体验肯定非常差,所以该session绑定方案使用场景非常有限

#编辑nginx主配置文件
upstream tomcats {
    ip_hash
#使用ip_hash算法调度
  server 192.168.111.4:8080;

  server 192.168.111.5:8080;

  }

二、session复制

适用于小型架构的服务器集群。开启web服务器的session复制功能,在集群中的几台服务器之间同步session对象,这样每台服务器都保存了用户的session信息,但是当集群规模比较大时,session复制机制会消耗大量系统资源以及网络资源

操作系统 IP地址 软件版本 主机名
CentOS 7 192.168.111.3 nginx1.14.2 Nginx
centos7 192.168.111.4 JDK1.7;Tomcat7.0.54 tnode1
centos7 192.168.111.5 JDK1.7;Tomcat7.0.54 tnode2

如有防火墙或selinux记得关闭或者修改相应规则

[root@localhost ~]# nginx -v
nginx version: nginx/1.14.2

[root@localhost ~]# vim /etc/hosts
    192.168.111.3   nginx
    192.168.111.4   tnode1
    192.168.111.5   tnode2

[root@localhost ~]# scp /etc/hosts 192.168.111.4:/etc/
[root@localhost ~]# scp /etc/hosts 192.168.111.5:/etc/
#配置hosts文件

#hostname nginx
#hostname tnode1
#hostname tnode2
修改主机名


[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
    http {
    ...
        upstream tomcatpool {
            server 192.168.111.4:8080 weight=1 max_fails=1 fail_timeout=10s;
            server 192.168.111.5:8080 weight=1 max_fails=1 fail_timeout=10s;
            }
    #以上为添加
    location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://tomcatpool;
        }
    #以上为修改添加最下面一行调用池


安装配置Tomcat。

[root@tnode1 ~]# tar zxf jdk-7u65-linux-x64.tar.gz 
[root@tnode1 ~]# mv jdk1.7.0_65/ /usr/local/java7
[root@tnode1 ~]# echo "PATH=$PATH:/usr/local/java7/bin" >> /etc/profile
[root@tnode1 ~]# source /etc/profile
[root@tnode1 ~]# rm -rf /usr/bin/java
[root@tnode1 ~]# java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
[root@tnode1 ~]# tar zxf apache-tomcat-7.0.54.tar.gz 
[root@tnode1 ~]# mv apache-tomcat-7.0.54 /usr/local/tomcat7


[root@tnode2 ~]# tar zxf jdk-7u65-linux-x64.tar.gz 
[root@tnode2 ~]# mv jdk1.7.0_65/ /usr/local/java7
[root@tnode2 ~]# echo "PATH=$PATH:/usr/local/java7/bin" >> /etc/profile
[root@tnode2 ~]# source /etc/profile
[root@tnode2 ~]# rm -rf /usr/bin/java
[root@tnode1 ~]# java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
[root@tnode2 ~]# tar zxf apache-tomcat-7.0.54.tar.gz 
[root@tnode2 ~]# mv apache-tomcat-7.0.54 /usr/local/tomcat7


[root@tnode1 ~]# vim /usr/local/tomcat7/webapps/ROOT/session.jsp
#测试页面
    Session ID:<%= session.getId() %><BR>
    SessionPort:<%= request.getServerPort() %>
    <% out.println("This tomcat server 192.168.111.4");%>


[root@tnode2 ~]# vim /usr/local/tomcat7/webapps/ROOT/session.jsp
    Session ID:<%= session.getId() %><BR>
    SessionPort:<%= request.getServerPort() %>
    <% out.println("This tomcat server 192.168.111.5");%>
    
#这是一个获取当前服务器所拥有的IP和sessionID的脚本页面



下面开始配置session复制(生产环境时一般10台以下使用该session解决方案

[root@tnode1 ~]# vim /usr/local/tomcat7/conf/server.xml 
    104     <Engine name="Catalina" defaultHost="localhost" jvmRoute="tnode1">
    #改行后面添加jvmroute配置项。
    109       <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
    #去掉注释
    
[root@tnode1 ~]# vim /usr/local/tomcat7/webapps/ROOT/WEB-INF/web.xml 
    </description> 
    #添加至倒数第二行


[root@tnode2 ~]# vim /usr/local/tomcat7/conf/server.xml 
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tnode2">
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
    
[root@tnode1 ~]# vim /usr/local/tomcat7/webapps/ROOT/WEB-INF/web.xml 
    </description> 
    #添加至倒数第二行



[root@tnode1 ~]# /usr/local/tomcat7/bin/shutdown.sh

[root@tnode1 ~]# /usr/local/tomcat7/bin/startup.sh 

[root@tnode2 ~]# /usr/local/tomcat7/bin/shutdown.sh 

[root@tnode2 ~]# /usr/local/tomcat7/bin/startup.sh 
    
客户端使用火狐浏览器输入:http://192.168.111.3/session.jsp来进行测试,并且刷新(别强制刷新,那样是新的sessionID)

三、使用 memcached 解决session问题

memcached是一套分布式的快取系统,相关数据都是在内存里,一旦服务重启或者死机,则数据必然丢失;memcached是键值对存储形式;在以下试验中,每个session都会在这两台memcached上进行分布式存储,有了冗余性,即使一台出问题也不影响工作。同样只适用于中小型架构。

Tomcat之session解决方案

以下的配置两台Tomcat一样

[root@tnode1 ~]# yum -y install libevent memcached
#安装memcached及其依赖

[root@tnode1 ~]# memcached -u root -m 512M -n 10 -f 2 -d -vvv -c 512
    //-u:运行用户必须是root身份
    //-m:指定使用物理机的多少内存
    //-n:chunk size的最小空间是多少字节
    //-f:chunk size大小增长的倍数默认1.25倍
    //-d:在后台启动
    //-vvv:显示详细信息
    //-c:memcached服务的最大连接数
Tomcat连接memcached所依赖的库文件:
javolution-5.5.1.jar                     memcached-session-manager-1.5.1.jar      msm-kryo-serializer-1.6.4.jar
kryo-1.03.jar                            memcached-session-manager-tc7-1.5.1.jar  reflectasm-0.9.jar
kryo-serializers-0.10.jar                minlog-1.2.jar                           spymemcached-2.7.3.jar
memcached-2.5.jar                        msm-javolution-serializer-1.5.1.jar 
将这些文件放到/usr/local/tomcat7/lib/目录下

配置文件连接memcached。
[root@tnode2 ~]# vim /usr/local/tomcat7/conf/context.xml 
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="memA:192.168.111.4:11211 memB:192.168.111.5:11211" requestUrilgnorePattern=".*\(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"/>
    
[root@tnode2 ~]# /usr/local/tomcat7/bin/shutdown.sh 
[root@tnode2 ~]# /usr/local/tomcat7/bin/startup.sh
#重启服务

测试页仍然使用以上的那个测试页

浏览器访问http://192.168.111.3/session.jsp测试,可以看到sessionID不变

四、使用 redis 解决session问题

注意:尽量保持系统环境的纯净

如果使用如上做完memcached环境接着做redis

1.rpm -e memcached-1...
2.vim /usr/local/tomcat7/conf/context.xml
3.pkill -9 memcached
4.删除相关jar包



安装部署redis
[root@tnode1 ~]# tar zxf redis-3.2.5.tar.gz 
[root@tnode1 ~]# yum -y install tcl
#依赖包

[root@tnode1 src]# mkdir /usr/local/redis/{bin,etc,var} -pv


[root@tnode1 src]# cp ~/redis-3.2.5/src/redis-benchmark redis-check-aof redis-cli redis-server /usr/local/redis/bin/
//redis-benchmark:读写性能测试工具
//redis-cli:redis命令行操作工具
//redis-server:redis服务的daemon启动程序
[root@tnode1 src]# cp ~/redis-3.2.5/redis.conf /usr/local/redis/etc/
//redis的主配置文件


[root@tnode1 src]# vim /usr/local/redis/etc/redis.conf
    128 daemonize yes
    #表示将redis启动在后台
    
    61 bind 0.0.0.0
    #监听所有主机


[root@tnode1 src]# /usr/local/redis/bin/redis-server /usr/local/redis/etc/redis.conf 
[root@tnode1 src]# netstat -anpt | grep redis
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      69432/redis-server  
#启动并且查看端口


Tomcat和redis连接需要用到如下包:
commons-logging-1.1.3.jar                jedis-2.5.2.jar                          tomcat-redis-session-manage-tomcat7.jar
commons-pool2-2.2.jar                    tomcat-juli.jar                          

[root@tnode1 ~]# vim /usr/local/tomcat7/conf/context.xml 
#连接redis配置
<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager" host="192.168.111.4" port="6379" database="0" maxInactiveInterval="60" />
#Context字段中添加如上,IP为redis服务器的IP。


#如下可以先把node2上该lib目录删掉,直接复制覆盖
[root@tnode1 ~]# scp -r /usr/local/tomcat7/lib root@192.168.111.5:/usr/local/tomcat7/lib

#如下是直接覆盖node2配置文件
[root@tnode1 ~]# scp /usr/local/tomcat7/conf/context.xml root@192.168.111.5:/usr/local/tomcat7/conf/

#然后node2上重启Tomcat服务,可多重启几遍顺便观察node1上的redis监视状态,并且时刻关注本机catalina.out日志变化是否异常。


#如下是正常情况下redis监视的状态输出
[root@tnode1 src]# /usr/local/redis/bin/redis-cli -p 6379 monitor

1556385116.932343 [0 192.168.111.4:37948] "EXPIRE" "DCF23D098140E899E20A996990F690D5" "1800"
1556385116.970109 [0 192.168.111.4:37948] "GET" "DCF23D098140E899E20A996990F690D5"
1556385116.972760 [0 192.168.111.4:37948] "EXPIRE" "DCF23D098140E899E20A996990F690D5" "1800"
1556385117.582753 [0 192.168.111.4:37948] "GET" "DCF23D098140E899E20A996990F690D5"
1556385117.584391 [0 192.168.111.4:37948] "EXPIRE" "DCF23D098140E899E20A996990F690D5" "1800"
1556385117.599639 [0 192.168.111.4:37948] "GET" "DCF23D098140E899E20A996990F690D5"
1556385117.600743 [0 192.168.111.4:37948] "EXPIRE" "DCF23D098140E899E20A996990F690D5" "1800"
1556385125.008432 [0 192.168.111.4:37948] "PING"
1556385155.006175 [0 192.168.111.4:37948] "PING"
1556386097.450914 [0 192.168.111.5:34118] "SETNX" "F7379EF99F21FD0BBF830056FEF162A0" "null"
1556386097.575639 [0 192.168.111.5:34118] "SET" "F7379EF99F21FD0BBF830056FEF162A0" "\xac\xed\x00\x05sr\x00Dcom.orangefunction.tomcat.redissessions.S
essionSerializationMetadataB\xd9\xd9\xf7v\xa2\xdbL\x03\x00\x01[\x00\x15sessionAttributesHasht\x00\x02[Bxpw\x14\x00\x00\x00\x10\x1f\xa2\xa9o\x15\x7f\xe1W\x9c\x9c\xc6\xc2\xb0\xd5\xe2\xa8xsr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01j3\x83F\xddsq\x00~\x00\x03\x00\x00\x01j3\x83F\xddsr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexq\x00~\x00\x04\x00\x00\a\bsr\x00\x11java.lang.Boolean\xcd r\x80\xd5\x9c\xfa\xee\x02\x00\x01Z\x00\x05valuexp\x01q\x00~\x00\nsq\x00~\x00\x03\x00\x00\x01j3\x83F\xddt\x00 F7379EF99F21FD0BBF830056FEF162A0sq\x00~\x00\a\x00\x00\x00\x00w\b\x00\x00\x01j3\x83F\xdd"1556386097.577377 [0 192.168.111.5:34118] "EXPIRE" "F7379EF99F21FD0BBF830056FEF162A0" "1800"
1556386097.586858 [0 192.168.111.5:34118] "EXPIRE" "F7379EF99F21FD0BBF830056FEF162A0" "1800"
1556386099.395455 [0 192.168.111.5:34118] "GET" "F7379EF99F21FD0BBF830056FEF162A0"
1556386099.403983 [0 192.168.111.5:34118] "EXPIRE" "F7379EF99F21FD0BBF830056FEF162A0" "1800"
1556386099.410867 [0 192.168.111.5:34118] "GET" "F7379EF99F21FD0BBF830056FEF162A0"
1556386099.413166 [0 192.168.111.5:34118] "EXPIRE" "F7379EF99F21FD0BBF830056FEF162A0" "1800"
1556386099.855877 [0 192.168.111.5:34118] "GET" "F7379EF99F21FD0BBF830056FEF162A0"
1556386099.857305 [0 192.168.111.5:34118] "EXPIRE" "F7379EF99F21FD0BBF830056FEF162A0" "1800"
1556386100.497947 [0 192.168.111.5:34118] "GET" "F7379EF99F21FD0BBF830056FEF162A0"



客户端访问http://192.168.111.3/session.jsp,是Nginx的地址来进行测试,正常时是sessionID不会变的

五、memcached和redis对比表

内存利用率 性能 数据持久化 其它
redis 键值对村存储利用率低于memcached,但使用hash结构存储则超过后者 只使用单核CPU,数据大小100K以下快于后者 支持数据持久化(保存到硬盘) Redis 支持数据的备份,即 master-slave 模式的数据备份,支持多种数据结构的存储
memcached 如上 可以使用多核,100K以上快于前者 自身不支持持久化,但可以结合其他数据库做架构如:memcached + bdb 两者性能都属于非常不错的,而且也都是开源免费。

Linux公社的RSS地址: https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2019-05/158709.htm


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Smashing Book

The Smashing Book

Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90

The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具