什么是 session
web-server
可以自动为同一个浏览器的访问用户自动创建 session
,提供存储功能。一般把用户信息和登录信息存到 session
中。
什么是session一致性问题
当后端只有一台 web-server
的时候,每次 http
请求,都能找到正确的 session
,问题是不能满足高可用,一台 server
挂了就完蛋了。
解决办法是冗余 + 故障转移,部署多台 web-server
,由 nginx
路由到不同的 web-server
。如果每次 http
都请求路由,不能保证路由到同一个 server
,这就是一致性问题。
解决 session 一致性的常用方案
一致性 hash
这是最先想到的解决方案,根据客户端 IP
做 hash
,保证同一个 IP
落在一个 web-server
上,即四层 hash
。
还可用根据业务字段做 hash
,例如 userId、cityId
,使用更灵活,即七层 hash
。但这样破坏了单一原则,让网关和业务关联,如非必要不推荐使用。
优点:
节省缓存,可用水平扩展( session
同步法是不行的,受内存限制)。
缺点:
部分服务重启,会丢失 session
,导致部分用户重新登录。
如果 hash
水平扩展,rehash
后 session
重新分布,会有一部分用户路由不到 session
。
session 同步
多 web-server
之间的 session
互相同步,这样每个 web-server
都包含全部的 session
信息。
优点:
每个 web-server
包含全部 session
,单个 server
故障不会丢信息,至少理论上是这样。
缺点:
浪费缓存,集群数量受内存限制,扩展受限。
客户端存储
登录信息保存到客户端,每次请求带着用户信息。服务端完全无状态化,方便扩展。
优点:
服务端不用存储。
缺点:
每次 http
请求携带用户信息,浪费外网流量;
session
在客户端,存在信息泄露风险;
cookie
存储信息不能太多。
后端集中存储
web-server
链接一个统一的存储,保存 session
信息,推荐存到 redis
集群,方便后续扩展。
优点:
没有信息泄露风险;
水平扩展不会丢数据;
缺点:
增加了一次网络请求,需要修改业务代码,查询 redis
。