集群WEB应用或多或少都会遇到session问题,多台服务器的情况下,session的要地存储会引起一些问题,影响用户体验。
配置Nginx负载策略,比如ip_hash
,使客户端绑定在固定服务器上,这样最终用户访问到的机器是固定的,所以session
存储在本地,不影响用户使用。但缺点主要有两项:
ip_hash
分配并不均匀,尤其是用于ip_hash
的Nginx不是最前端时,可能无法使用此策略
假如不考虑负载均匀问题,仍然存在的问题是,当后端某台机器宕掉时,这台机器上所有的session
都会失去,假如session
中记录的用户的认证状态,那么用户将变成未认证状态
服务器(Nginx代理的服务器)间进行session
广播,这种方式存在的问题是,随着集群规模的扩张,广播的性能会变得很差,一般不推荐使用
使用session
共享方案,具体使用redis
还是使用memcached
这里不讨论,这里假设使用redis
,方法也很简单,将session
的存储实现用redis
替换掉,也可以使用HttpServletRequestWrapper
方式来动态修改session
的memcached-session-manager
或者spring-session
等实现,除了集中存储对性能(相对于本地存储)有一定影响,其它几乎完美,前提是实现代码够强壮
个人也想了一个有缺陷的办法,反正也只是设想,从来没用过。session
广播的方式随着集群规模扩大,性能会下降,那么就不所有机器间广播,可以两台、三台之间广播,假设以两台为一组,所有集群中的服务器,以两台为单位分组,相互广播session
,这时只需要保证相互广播的两台机器不同时挂掉即可(^_^ 貌似无法保证的吧!)
[2016/9/1]
个人认为完全可以避免使用session
,servlet
系的应用做分布式本就有很多限制,如果要实现分布式,最好的办法是利用http
的无状态特性来实现,当然,用户登录、购物车等信息确实需要进行状态存储,这些完全可以直接存储到第三方存储中,比如:redis
、mysql
等,其本质上类似于session
共享方案,但相对更加激进。
The absolute part of session you are talking about here is about storing login information, right?
If yes, then unified login service should also be a solution