首先明确一点,单服务器是没有这个问题的,所有的seseion都在一个web容器中。如果是集群或者分布式环境下,多台机器或多个web容器会出现Session不一致的问题。解决办法有以下几种:
一、session同步
在多个web容器中相互同步session数据,这样,所有的web容器就会保持有所有的session数据。
不足之处:
session同步需要数据传输,有一定的延时 ;所有web容器保存有所有session数据,较占内存,且无法扩展。
二、会话保持(session sticky)
即把用户的请求固定在一个server上,用户第一次登录请求后,以后所有的请求就全落在这个server上。nginx就支持这个功能。
不足之处:
缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上时,他的session信息都将失效
三、数据库存储session
把session存入数据库,这样session就跟web 容器没有关联了,web 容器发生故障或者重启都不会影响session,并且安全风险也小。
目前负责的项目中,就是把APP客户端的token存入到数据库中,用户每次业务请求(除了登录请求)都需要把token作为参数放在http header中,然后再去后台数据库中作比对,如果没有匹配的token信息,说明用户token已经失效或者是非法请求,需要用户重新登录。
不足之处:
session读取频率很高,频繁访问数据库,对数据库造成很大压力。
四、缓存存储session
这个其实跟第三条较为相似,都是把session单独存储(独立于web容器),这里可以用redis和memcached进行存储。
不足之处:
对缓存内存要求较高,且缓存一旦挂掉,session数据也没了。
总结:具体业务具体分析,寻找最合适的。核心思想是,session是有状态的,service层是无状态的,特别是在分布式环境下,有状态的session和无状态的服务不要耦合在一起。