问题
假设我们有4台服务器,1台做负载均衡器,其余3台做web节点服务器,并将这3台服务器做一个负载均衡。我们给这3台服务器标记一下,为1、2、3号服,假设某个用户发出登录请求,正好落在1号服上,登录成功,接着用户又发出了第2个请求,这个时候正好落在了2号服务器上,这里我用的是Nginx服务器,Nginx服务器集群默认采用的是轮询算法,所以会接着落在第2号服务器上,但是尴尬的是,我的用户session信息保存在1号服务器上的,所以会导致第2次请求的时候会显示没有登录。
解决思路
解决方法主要有两种,一种是在负载均衡服务器上配置一个ip_hash
,另一种就是将session保存到mysql
或memcached
中,还可以搭建一个单点的服务器专门用来登录。
设置ip_hash
在负载均衡服务器上设置ip_hash,如:
#服务器池
upstream www_server_pools{
ip_hash;
server 192.168.1.1 80;
server 192.168.1.2 80;
server 192.168.1.3 80;
}
server {
listen 80;
server_name test.com;
location / {
proxy_pass http://www_server_pools;
}
}
配置了ip_hash
的话,只要是一个ip发出的请求都会落在同一台服务器上,这样可以解决session共享问题,但是无法保证1:1的负载均衡,因为在国内大多数公司都是NAT上网模式,多个客户端都对应一个外部IP,所以,这些客户端都会被分配到同一个节点服务器上,从而导致请求分配不均。
将session持久化
用户登录的时候,可以将session信息保存到mysql或者memcached中,这样的话,如果在发出请求,我们从数据库中查询是否存在session信息,然后进行的业务逻辑。