如何实现web应用会话保持
前言
所谓的会话保持是在网络层面,在应用与服务器建立tcp三次握手连接之后,指在网络通信中,为了保持客户端与服务器之间的连接状态而采取的一种机制。在传统的HTTP协议中,HTTP是一种无状态的协议,每次请求都是独立的,服务器无法识别不同请求之间的关联性。而会话保持机制则通过在客户端和服务器之间维护一个会话标识,使得服务器可以识别并保持与客户端的连接状态。
一、会话保持机制
常见的会话保持机制包括:
Cookie:服务器通过在响应中设置一个包含会话标识的Cookie,客户端在后续的请求中通过发送该Cookie来维持会话状态。
Session:服务器在接收到客户端请求时,为每个会话创建一个唯一的标识,并将该标识存储在服务器端。客户端在后续的请求中通过发送该标识来维持会话状态。
Token:服务器通过生成一个包含会话信息的令牌(Token),并将该令牌发送给客户端。客户端在后续的请求中通过发送该令牌来维持会话状态。
这些机制都可以实现会话保持,但具体选择哪种机制取决于应用场景和需求。
二、实现方式
1、首先服务器收到客户端请求后,会生成一个session ID返回给客户端,有的应用会放到自己的redis数据库里,这个服务器多个部署单元如果公用这个数据库的话,就能共享session ID,不管服务请求发送到哪个服务器,都能保持会话。
2、客户端收到session ID后,会把他放到自己的Cookie里,在后续的请求中都会发送此cookie,相当于加了一个报文头,服务器通过此报文中session id找到用户信息,判断用户状态。
3、nginx的会话保持
nginx有两种会话保持方案
- 基于ip_hash
- 基于cookie
第一种会根据ip来给客户分配固定的服务器,这种情况下可能会导致负载失衡,因为同一个局域网的客户都会分到同一台服务器。
ip_hash语法:
upstream web {
ip_hash;
server www.123.com;
server www.111.com;
}
第二种是使用sticky_cookie_insert启用会话亲缘关系,这会导致来自同一客户端的请求被传递到一组服务器的同一台服务器。以来用户的cookie来判断,而cookie里又包含用户分配的session id。
sticky_cookie_insert语法:
upstream web{
server www.123.com;
server www.111.com;
sticky expires=2h domain=3evip.cn path=/;
}
说明:
expires:设置浏览器中保持cookie的时间
domain:定义cookie的域
path:为cookie定义路径
4、nginx的keepalive集群的会话保持
一般nginx以集群化部署,多台nginx构成一个keepalive集群,以一个vip对外提供服务,由集群随机分配流量到其中一台nginx。在这种集群部署情况下,可以采用persistence_timeout参数来保持会话同一时间只连接一个服务器,当然,假如在nginx都已经做了相关会话保持的配置,这一步其实是可有可无的。
三、可能的问题
当用户在登录后网络方式变化时,比如连接到了不同的wifi,会话保持是否还能实现?
此场景下,用户ip地址变了,如果nginx采用ip_hash方法,肯定会被分到不同服务器,session也就断了,但如果采用sticky_cookie_insert的负载均衡方式,由于用户cookie中的session ID不变,因此服务器通过cookie判断的话会分到相同服务器,能够做到会话保持,但是假如用户的cookie过期的话就可能产生问题。
总结
例如:以上就是今天要讲的内容,本文仅仅简单介绍了会话保持的原理,并分析的影响会话保持的场景和策略。