第1个回答 2022-06-16
在单台服务器情况下session处理比较简单,一旦到了集群环境中,我们就必须考虑用户和会话的问题,如果不加处理的话,一旦后端IP轮询切换,会话cookies找不到session,会话就中断了。在此情景下,通常有以下5种解决方案。
将每一个用户和后端服务器绑定,这样用户的会话就会一直落在同一台服务器上,这是成本最小的解决方案,只需要修改Nginx服务器的配置即可。如果是在比较老的架构上,推荐这种改造方案。
这种解决解决方案也存在局限性,比如某台服务器挂了切换到另一台服务器,对应的会话也就丢了。还有另外一个问题,如果前端用了CDN的话,客户端IP变化的频率可能是很高的,有可能一个小时或更短时间内就变一次,这在校园网的网络环境下很容易产生这种情况。
顾名思义,Session复制就是让集群里的每台服务器都存储整个集群所有服务器上的全部session。这样一旦某台服务器挂了,用户切换到其他服务器上也能访问到一样的session数据。这种解决方案不好的地方在于进行session复制需要额外的网络开销和系统资源,当服务器较多或session中存储的数据量大的时候,这个问题尤为明显。
Session复制本身的操作是比较复杂,但是对于服务器来说,配置比较简单,但性能是个很大的问题。当集群中服务器数量大于两台时就比较吃力了,总之这是一种比较早期时候的解决方案。
sticky方案和方案1类似,但是sticky能把会话死死地粘滞在其中一台服务器上,算是对方案1的补充,可以避免在CDN网络波动下的IP冲突造成的会话丢失。但是依然无法解决服务器挂掉导致会话丢失的问题。
基于Redis等NoSQL的session集中存储方案,是目前最流行的解决方案,早期用MySQL来存储。引入Redis的方案除了会增加系统复杂度外,依然还有以下几个问题:
使用纯cookie,不使用session,天然分布式。存在问题:
需要注意的是,如果应用需要做“禁止同时登录”的需求时,用Cookie的话解决起来会麻烦很多。
另外可以把cookie换成token等方式验证用户,每次请求带上token作为会话凭据。