http协议是无状态的,即你连续访问某个网站100次和访问1次对服务器来说是没有区别的,因为它记不住你。那么在一些场合,确实需要服务器记住当前用户怎么办?比如用户登录邮箱后,接下来要收邮件、写邮件,总不能每次操作都让用户输入用户名和密码,为了解决这个问题,session的方案就被提了出来,事实上它并不是什么新技术,而且不能脱离http协议以及任何现有的web技术
session的常见实现形式是绘画cookie(session cookie),即未设置过期时间的cookie,这个cookie的默认生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。实现机制是当用户发起一个请求的时候,服务器会检查该请求中是否包含sessionid,如果未包含,则系统会创造一个名为JESSIONID的输出cookie返回给浏览器(只放入内存,并不存在硬盘中),并将其以HashTable的形式写到服务器的内存里面;当已经包含sessionid时,服务端会检查找到与该session相匹配的信息,如果存在则直接使用该sessionid,若不存在则重新生成新的session。这里需要注意的是session始终是由服务端创建的,并非浏览器自己生成的。但是浏览器的cookie被禁止后session就需要用get方法的URL重写的机制或使用POST方法提交隐藏表单的形式来实现。
session共享
首先我们应该明白,为什么要实现共享,如果你的网站是存放在一个机器上,那么是不存在这个问题的,因为会话数据就在这台机器上,但是如果你使用负载均衡吧请求分发到不同的机器呢?这个时候会话id在客户端是没有问题的,但是如果用户的两次请求到了两台不同的机器上,而它的session数据可能存在其中一台机器,这个时候就会出现取不到session的情况,那么如何实现session的共享就成了一个问题
-
session一致性解决方案
- IP绑定
- nginx的ip_hash实现,同一个ip的调度
- session黏性
- Tengine支持,同一个session的调度
- session复制集群
- Tomcat 本身带有复制session的功能(实现比较复杂,有兴趣自己查阅相关资料,使用比较少)
- 共享session
- 需要转么管理session的软件,msm(memcached-session-manager)
- memcached缓存服务,可以和tomcat整合,帮助tomcat共享管理session
- 需要转么管理session的软件,msm(memcached-session-manager)
- IP绑定
-
nginx IP绑定配置
upstream backend {
server 192.168.214.202:8080;
server 192.168.214.203:8080;
ip_hash;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD/HTTP/1.0\r\n\r\n";
check_http_expert_alive http_2xx http_3xx;
}
- 会话保持(session黏性)
- ngx_http_upstream_session_sticky_module
- 该模块属于负载均衡模块,通过cookie实现客户端与后端服务器的会话保持,在一定条件下可以保证同一个客户端访问的都是同一个后端服务器。
- mode 设置cookie的模式
- insert:在回复本模块通过set-Cookie头直接插入相应名称的cookie。
- prefix:不会生成新的cookie,但会在响应的coolie值前面加上特定的前缀,当浏览器带着这个有特定标识的cookie再次请求时,模块传给后端服务前先删除加入的前缀,后端服务拿到的还是原来的cookie值,这些动作对后端透明。如:“Coolie:Name=SRV~VALUE”。
- rewrite:使用服务端标识覆盖后端设置的用于session sticky的cookie。如果后端服务在响应头中没有设置该cookie,则认为该请求不需要进行session sticky,使用这种模式。后端服务可以控制哪些请求西药session sticky,哪些请求不需要
- tengine 具有session sticky功能
upstream backend {
server 192.168.214.202:8080;
server 192.168.214.203:8080;
session_sticky;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD/HTTP/1.0\r\n\r\n";
check_http_expert_alive http_2xx http_3xx;
}
#### insert + indirect模式
#### option
### - indirect:不会将session sticky的cookie传送给后端服务
### - direct:与indirect相反
upstream backend {
server 192.168.214.202:8080;
server 192.168.214.203:8080;
session_sticky cookie=mysid fallbak=on path=/ mode=insert option=indirect;
check interval=3000 rise=2 fall=5 timeout=1000 type=http;
check_http_send "HEAD/HTTP/1.0\r\n\r\n";
check_http_expert_alive http_2xx http_3xx;
}
server {
location / {
session_sticky_hide_cookie upstream=backend;
proxy_pass http://backend;
}
}