Session机制
JSESSIONID是Session的标识,当客户端请求服务器端的时候,服务器端会检查是否已经给这个客户端创建过Session,也就是看客户端的请求中的header是否有Cookie:JSESSIONID=…,如果客户端请求包含JSESSIONID,那么服务器端可以根据JSESSIONID找到对应的Session;如果没有,则服务端认为该客户端第一次访问,会在response中增加header,即Set-Cookie:JSESSIONID=…,当客户端收到该response后就会被设置Cookie,以后的请求都会携带该Cookie,保证Session的一致性;
1 Session机制测试
1.1 模拟第一次访问(无JSESSION)
1.2 模拟非第一次访问(有JSESSIONID)
2 分布式Session实现
2.1 伪分布式Session
2.1.1 nginx ip_hash
根据客户端的IP,将请求分配到不同的服务器上;
配置如下:
upstream my_upstream {
ip_hash;
server 10.20.35.11:8001;
server 10.20.35.11:8002;
}
2.1.2 nginx sticky
https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/overview
下载之后通过--add-module重新编译nginx;
配置如下:
upstream my_upstream{
sticky;
server 10.20.35.11:8001;
server 10.20.35.11:8002;
}
实现原理:
Sticky是nginx的一个模块,它是基于cookie的一种nginx的负载均衡解决方案,通过分发和识别cookie,来使同一个客户端的请求落在同一台服务器上,默认标识名为route
1 客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。
2 后端服务器处理完请求,将响应数据返回给nginx。
3 此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值
4 客户端接收请求,并保存带route的cookie。
5 当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器。
2.2 真分布式Session
后端实现:
1 继承HttpSessionWrapper,比如DistributeHttpSessionWrapper,覆盖getAttributeNames、getAttribute、setAttribute等方法,改为到一个公共的地方读写session属性,比如DB、Memcached、Redis等;
javax.servlet.http.HttpSession
2 继承HttpServletRequestWrapper,比如DistributeHttpServletRequestWrapper,覆盖getSession方法,改为返回DistributeHttpSessionWrapper;
javax.servlet.http.HttpServletRequestWrapper
2 继承Filter,比如DistributeSessionFilter,覆盖doFilter方法,在调用链中将HttpServletRequest替换为DistributeHttpServletRequestWrapper;
javax.servlet.Filter