Session保持

 Session保持

一.Session本质

http协议是无状态的,服务端对于客户端来说是透明的,连续访问某个网页100次和访问1次对服务器来说是没有区别对待的,因为它记不住你。
 但是,在一些场合,确实需要服务器记住当前用户怎么办?比如用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入用户名和密码吧,为了解决这个问题,session的方案就被提了出来,事实上它并不是什么新技术,而且也不能脱离http协议以及任何现有的web技术。

二.关于Session共享

首先,单机环境不存在session共享的问题,但是无法保证高可用,但是如果你使用了负载均衡把请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session数据的情况,于是session的共享就成了一个问题。

三.Session共享解决方案

1.采用Nginx负载均衡器,采用的ip_hash来代替默认的轮询方式,即可以将某客户端IP的请求通过哈希算法定位到同一台后端web服务器上,这样避免了session丢失,解决了session问题。
ip_hash指令无法保证后端服务器的负载均衡,可能有些后端服务器接收的请求多,有些后端服务器接收的请求少;这样失去了负载均衡的意义。

2.将用户的登录session信息写进后端的Mysql数据库,这个在后面的CMS系统中也实现了,效果也不错;但是,用数据库来同步session,会加大数据库的IO,增加数据库的负担。而且数据库读写速度较慢,不利于session的适时同步,不推荐。
后来我提出了折衷方案,如果Nginx并发连接数(即Nginx负载均衡器的NginxStatus的 active connections)>2000,即采用将session写进MySQL数据库的方法;如果并发数小的话,ip_hash效果也是相当好的。
可参考:http://blog.csdn.net/donggang1992/article/details/51095551

3.Session复制,适用于接入层集群较少时,因为session复制占用服务器资源,存储占内存

例如:可以将session缓存到redis中,达到session复制的目的。目前此种方案是 nginx + redis + tomcat 实现的

4.Session绑定,主从复制   ************【ip_hsah 未尝试主从复制】**************

5.客户端cookie保存Session


6.Session集群

一.使用 filter 方法存储(未实现

这种方法比较推荐,因为它的服务器使用范围比较多,不仅限于 tomcat ,而且实现的原理比较简单容易控制。
可以使用 memcached-session-filter
官方网址:http://code.google.com/p/memcached-session-filter/
官方介绍:解决集群环境下java web容器session共享,使用filter拦截器和memcached实现。在tomcat 6和websphere 8测试通过,现网并发2000,日PV量1100万。
暂不支持session event包括create destory 和 attribute change
东西很不错,体积很小,不过这个东东要和 spring 一起使用,而且要求存储到 memcached 的对象要实现 java 的序列化接口
大家也知道,java 本身的序列化性能也很一般。
我将其简单扩展了一下,不再依赖 spring ,并且利用 javolution 实现序列化,缓存的对象不再有限制。
暂时没有发现 redis 的实现,后面将自己实现使用 redis 存储并且序列化使用 kyro ,详细情况有时间再单独写出来。

二.基于Tomcat本身的session集群共享未实现

问题:配置完成,但是无效

参考的是:tomcat session共享;

三.使用 tomcat session manager 方法存储

这种方法服务器只能使用 tomcat ,但网上有针对 memcached 和 redis 实现,直接配置就行了。 针对Redis,已实践

1.环境准备

Tomcat集群

IP 主机名 端口号
192.168.1.111 edu-web-01 8081
192.168.1.112 edu-web-02 8081

Redis集群

通过TWEMPROXY构建的Redis集群

192.168.1.122 edu-redis-01 6660/6661
192.168.1.123 edu-redis-02 6661
192.168.1.124 edu-redis-03 6661

相关命令:(含配置文件地址)

需要在192.168.1.122,123,124 上分别启动:
SSDB 7770 7771 8880 8881
nohup /usr/local/ssdb/ssdb-server   /usr/local/ssdb-master/ssdb_basic_7770.conf &  
nohup /usr/local/ssdb/ssdb-server   /usr/local/ssdb-master/ssdb_basic_7771.conf &  
nohup /usr/local/ssdb/ssdb-server   /usr/local/ssdb-master/ssdb_desc_8880.conf  &  
nohup /usr/local/ssdb/ssdb-server   /usr/local/ssdb-master/ssdb_desc_8880.conf  &  

REDIS 
192.168.1.122:6660 6661
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6660.conf &
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6661.conf &
192.168.1.123 6661
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6661.conf &
192.168.1.124 6661
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis_6661.conf &

启动Twemproxy
nutcracker.init {start|stop|status|restart|reload|condrestart}
nutcracker -d -c /usr/local/twemproxy/conf/nutcracker.yml -p /usr/local/twemproxy/run/redisproxy.pid -o /usr/local/twemproxy/run/redisproxy.log

测试:

redis-cli -h 192.168.1.122 -p 1115

2.配置Tomcat

2.1 新增jar包,将这3个jar包放到Tomcat的lib目录下

tomcat-redis-session-manager-1.2-tomcat-7.jar
jedis-2.1.0.jar
commons-pool-1.6.jar

2.2设置Tomcat配置文件

修改 context.xml 文件,在<context></context>内新增

<Context>

    <!-- Default set of monitored resources -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->

    <!-- Uncomment this to enable Comet connection tacking (provides events
         on session expiration as well as webapp lifecycle) -->
    <!--
    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />
    -->

	<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve"/>
	<Manager className="com.radiadesign.catalina.session.RedisSessionManager" database="0" host="192.168.1.122" maxInactiveInterval="60" port="1115"/>
</Context>

 注:我在server.xml配置时出现问题,同时在<context>内配置一开始也没成功,原因未查

2.3  运行测试环境

将WEB项目分别添加到2个Tomcat中并启动。
在test1应用的index.jsp中增加如下代码
<%
session.setAttribute("shareSession", "redis share Session")
%>
<a href="/test2">test2 index.jsp</a>
在test2应用的index.jsp中增加如下代码
<%=session.getAttribute("shareSession")%>(输出为NULL)
分别访问Tomcat1和Tomcat2,发现两边浏览器的jsessionid是一样的,在Redis控制台运行key *打印出来的就是共享的jsessionid

参考的是:基于Redis缓存的Session共享测试

此外,还可以使用memcache,未实践

1、修改 tomcat 的 conf 目录下的 context.xml 文件:
  <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"    memcachedNodes="n1:localhost:11211 n2:localhost:11212"     failoverNodes="n2"   
  requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"     sessionBackupAsync="false"      sessionBackupTimeout="100"      transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"     copyCollectionsForSerialization="false"    />;

2、以上是以 1.3 版为例子,需要用的 jar 包:
memcached-session-manager-1.3.0.jar
msm-javolution-serializer-1.3.0.jar
javolution-5.4.3.1.jar
memcached-2.4.2.jar

四.基于terracotta 服务器共享

 参考:http://www.cnblogs.com/interdrp/p/4056525.html 待实现



猜你喜欢

转载自zjjndnr.iteye.com/blog/2388522