分布式架构下,Session 共享有什么方案
- 采用无状态服务,抛弃session
- 存入cookie(有安全风险)
- 服务器之间进行 Session 同步,这样可以保证每个服务器上都有全部的 Session 信息,不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败;
- IP 绑定策略 使用 Nginx (或其他复杂均衡软硬件)中的 IP 绑定策略,同一个 IP 只能在指定的同一个机器访问,但是这样做失去了负载均衡的意义,当挂掉一台服务器的时候,会影响一批用户的使用,风险很大;
- 使用 Redis 存储 把 Session 放到 Redis 中存储,虽然架构上变得复杂,并且需要多访问一次 Redis ,但是这种方案带来的好处也是很大的:
- 实现了 Session 共享;
- 可以水平扩展(增加 Redis 服务器);
- 服务器重启 Session 不丢失(不过也要注意 Session 在 Redis 中的刷新/失效机制);
- 不仅可以跨服务器 Session 共享,甚至可以跨平台(例如网页端和 APP 端)。
分布式会话Session
如何解决分布式会话问题?
完成用户的状态认证 原先的session适合单机版的方式,
- 单机:单体的项目,session中,服务端自动生成cookie;
- 多个tomcat集群,配置nginx的ip_hash,这样客户端的Ip不变,路由到的tomcat服务器就不会变。
分布式 解决方案:
1. 有状态的方案
服务端依然要存储用户信息,存储有效凭证
生成cookie(user:token::uuid),从而确认存储在redis中的凭证信息。
uuid等同于原先的sessionId。
有状态的方式需要内存空间来存储用户信息。
2. 无状态的方案
服务端不需要存储用户状态信息。
消耗CPU资源来计算,基于算法,生产令牌(字符串),基于算法,核对令牌。
JWT的方式
token(用户本身的信息+时效信息)
依赖解析的结构,如果发生异常,说明凭证已过时效,没有异常说明状态正常。
cookie之所以能成功,有一个重要的前提。
所有的子系统,同父域的情况下,无法实现跨域。
jwt的组成
头部(header)
有效载荷(Payload)
签名(signature)
header 头部
header是一段json,经过base64编码变成一段字符串,编码前后对比图如图所示typ:
token的类型,这里固定为JWT
alg:使用的hash算法,例如:HMAC SHA256或者RSA
payload 有效载荷
存储需要传递的信息,如用户ID、用户名等 还包含元数据,如过期时间、发布人等
与header不同,payload可以加密
signature 签名
对header和payload部分进行签名
保证token在传输的过程中没有被篡改或者损坏