分布式Session的问题

问题描述

当我们做负载均衡时,可能用户登录后,Session信息保存在机器A,但是下订单时,请求发送到了机器B。

由于机器B上没有用户的Session数据,导致无法识别该用户是谁,那么就会需要再次登录一遍,用户体验差。

解决办法

方法一:IP_Hash做负载均衡

该方法能保证一个IP发送的请求都会发送到某台固定的服务器上,从而避免分布式Session问题。

缺点:

  • 单点故障问题,如果某台服务器挂了,那么有一部分用户无法再使用服务,因为请求是固定发送到该服务器上的。

image.png

方法二:Session复制

即在多台服务器上做Session的复制,保证每台机器都有用户的session。

缺点:

  • 开销非常大。因为每一次都需要进行广播来保证每台机器上有用户的Session;

image.png

方法三:Session Center

使用Session中心来统一保存用户的Session。例如Redis。

该方案比方法一和方法二都要好。也是比较普遍的方案,但是也有一些不足。

缺点:

  • 使用了额外的技术

image.png

数据库优化

换数据库

例如,从mySQL换成Redis,Oracle等。

分库分表和读写分离

方式一:JDBC层的分库分表,例如ShardingSphere,TDDL

该方式将分库分表的逻辑放在应用层,即通过JAVA语言来完成。
image.png

优点:

  • 性能高

缺点:

  • 不能跨语言,而且会对业务代码有侵入性

方式二:Proxy代理层的分库分表

该方式多加一层代理层,分库分表的逻辑放在代理层来处理。

例如:mycat,mysql-proxy

优点:

  • 可以跨语言
  • 无侵入性

缺点:

  • 因为多了一次通信过程,所以效率要比方式一低一点。

image.png

幂等性接口

定义

幂等性本来是数学上的概念,表示做一次变换和做N次变换得到的结果是一样的。

在编程方面,幂等性接口表示:
对一个接口调用一次或者N次, 对系统的影响是一样的。

举个例子:
抢红包只允许抢一次,即便你抢多次,也和抢一次的得到的钱是一样的。

再举个例子:
支付接口,对于同一笔订单,只允许支付一次,即便调用该接口多次,也只会支付一次的钱。

解决方案

方案一:全局唯一ID

例如,对于一笔订单设置唯一ID,如果该ID已经存在,就不会再去创建该订单了。

方案二:去重表

和全局唯一ID的思路一样,只是将该去重表放进Redis中维护,表里存在该ID就不创建了。

方案三:状态机

不太懂目前