所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。但是在服务集群中,session共享往往是一个比较头疼的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就会丢失,一般情况下,session不可跨服务器而存在。于是就有了分布式系统的session共享问题。
再说方案之前,老规矩,走一波概念:
session:
当新客户端发现一个HTTP请求时服务端会创建一个session.并分配一个sessionID作为服务端来客户端的识别,session对象会保存在服务端.此时session对象处天NEW STATE状态,如果调用 session.isNew()则返回true.
当服务器处理完后,会将sessionID同response 一起传回客户端,并将其存到cookie中;当客户端再发送请求的时候.会将sessionID连同request一起发送给服务端;服务端再根据传过来的sessionID将这次request与保存在服务端的session对象联系起来.此时的session对象已不是NEWSTATE状态.这样循环多次.直到超时或销毁.
注:当禁用cookie时也是不能使用session的;
cookie:
cookie是在客户端保存的方案.而session是在服务端保存的方案.如果cookie不设定时间的话就表视它的生命周期为浏览器会话的期间,只要关闭IE,cookie就消失了,这种cookie被称为会话cookie.其一般不保存在硬盘上.而是保存在内存中,如果设置了过期时间.那么浏览器会把cookie保存到硬盘中,再次打IE时会依然有效.直到它的有效期超时;
注:存储在硬盘中的cookie可以在不同IE间共享;
如何实现session共享呢?有以下几种方案,亲们可以根据自己的业务场景,访问情况等具体选择其中一个解决方案即可。
这是我以前采用的方式,简单,高效。比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现。
问题:session中数据不能太多,最好只有个用户id。
可能大部分应用服务器都提供了session复制的功能来实现集群,tomcat,jboss,was都提供了这样的功能。
问题:性能随着服务器增加急剧下降,而且容易引起广播风暴;session数据需要序列化,影响性能。
这种方式跟数据库类似,不过因为是内存存取的,性能自然要比数据库好多了。
问题:程序需要定制,增加了工作量;存入memcached中的数据都需要序列化,效率较低;memcached服务器一死,所有session全丢。
那么今天,我们以tomcat+nginx+redis架构模式讲解下,如实使用redis保存session,从而实现集群环境下的session共享问题。
环境准备:
1:redis配置(192.168.1.31:16300)
2:tomcat配置
tomcat-8081(192.168.1.30:8081)
tomcat-8082(192.168.1.30:8082)
3:nginx配置(192.168.1.32)
不会配置负载的可以参考 (nginx+tomcat负载均衡)
首先,是配置tomcat,使其将session保存到redis上。有两种方法,也是在server.xml或context.xml中配置,不同的是memcached只需要添加一个manager标签,而redis需要增加的内容如下:(注意:valve标签一定要在manager前面。)
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="192.168.159.31"
port="16300"
database="0"
maxInactiveInterval="60"/>
其次,配置nginx,用于测试session保持共享。
upstream redis.test.com {
server 192.168.1.30:8081;
server 192.168.1.30:8082;
}
log_format www_xy_com '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for"';
server{
listen 80;
server_name redis.test.com;
location / {
proxy_pass http://redis.test.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
access_log /data/base_files/logs/redis.xxy.log www_xy_com;
}
最后,将你的应用放到两个tomcat中,并依次启动redis、tomcat、nginx。访问你的nginx,可以发现两个tomcat中的session可以保持共享了。