分布式session

分布式session 在单体服务器的年代,Session 直接保存在服务器中,是没有问题的,而且实现起来很容易。 但是随着分布式架构的流行,单个服务器已经不能满足系统的需要了,通常都会把系统部署在多台服务器上,通过负载均衡把请求分发到其中的一台服务器上; 那么很有可能第一次请求访问的 A 服务器,创建了 Session ,但是第二次访问到了 B 服务器,这时就会出现取不到 Session 的情况; 于是,分布式架构中,Session 共享就成了一个很大的问题。 解决方案 1. session同步 思路:多个web-server之间相互同步session,这样每个web-server之间都包含全部的session 优点:web-server支持的功能,应用程序不需要修改代码 不足: 1.session的同步需要数据传输,占内网带宽,有时延。 2.所有web-server都包含所有session数据,数据量受内存限制,无法水平扩展。 3.主从架构固有的保证一致性会牺牲可用性的特定,但进行主从同步时,登陆的请求将被阻塞,显然不符合用户实际需求。 2. 客户端存储法 思路:服务端存储所有用户的session,内存占用较大,可以将session存储到浏览器cookie中 优点:服务端不需要存储 缺点: 1.每次http请求都携带session,占外网带宽 2.数据存储在端上,并在网络传输,存在泄漏、篡改、窃取等安全隐患 3.session存储的数据大小受cookie限制 “端存储”的方案虽然不常用,但确实是一种思路。 3. 反向代理hash一致性 思路:使用 Nginx (或其他复杂均衡软硬件)中的 IP 绑定策略,同一个 IP 只能在指定的同一个机器访问,但是这样做失去了负载均衡的意义,当挂掉一台服务器的时候,会影响一批用户的使用,风险很大; 反向代理层做逻辑处理 方案一:ip进行hash 反向代理层使用用户ip来做hash,以保证同一个ip的请求落在同一个web-server上. 方案二:含有业务属性的字段hash 反向代理使用http协议中的某些业务属性来做hash,例如sid,city_id,user_id等,能够更加灵活的实施hash策略,以保证同一个浏览器用户的请求落在同一个web-server(即不同的user_id对应不同的web-server). 总结:让专业的软件做专业的事情,反向代理就负责转发,尽量不要引入应用层业务属性,除非不得不这么做(例如,有时候多机房多活需要按照业务属性路由到不同机房的web-server)。 4. 后端统一集中存储(主流方案) 思路:将session存储在web-server后端的存储层,数据库或者缓存 优点: 1.没有安全隐患 2.可以水平扩展,数据库/缓存水平切分即可,可以存储较多的session。 3.web-server重启或者扩容都不会有session丢失 不足:增加了一次网络调用,并且需要修改应用代码。 对于db存储还是cache,个人推荐后者:session读取的频率会很高,数据库压力会比较大。 如果有session高可用需求,cache可以做高可用,但大部分情况下session可以丢失,一般也不需要考虑高可用。

April 21, 2024 · 1 min · Leanku