session共享 原创
问题背景
在分布式系统中,用户登录信息在服务器间共享问题。当一个客户端发送一个请求(无session),通过nginx将第一次请求分发给服务器1,服务器判断无session,就让那个客户进行登录操作,并得到响应,此时客户端会存储一个来自服务器1响应的session,并存储在客户端。
当客户端发送第二次请求的时候,此时本次请求已经携带了session(跳过登录),nginx却将请求分发给服务器2,因为服务器2中没有session,所以无法与客户端session进行对应。所以程序会出现异常或是报错,无法正常响应。
解决方案:
方案1 - 使用session粘滞方案
使用nginx负载均衡ip hash策略的方式固定用户的请求达到同一台服务器上
优势:不需要改动项目代码,无需额外开销
缺点:如果某台服务器挂掉了,这台服务器上的session都会丢失,所有分配到这台服务器上的用户都会出现访问异常获取不到登录信息导致需要用户重新登录
方案2 - session持久化方案
将session数据保存到数据库 如mysql中
优点:不同的服务器可以根据用户上传的sessionID从数据库进行信息查询
缺点:如果海量请求同时发送,容易造成数据库服务器压力过大从而崩溃等问题
方案3 - 使用redis解决
任何形式的token识别校验,需要唯一不重复的token
用户登录成功之后将用户信息保存到redis中,然后生成一个对应查询的token,服务器将token返回给客户端,客户端之后的请求都带上这个token,不管是哪个服务器拿到token之后都可以直接在redis中查询出用户信息
优点:代码灵活,基于分布式Redis,可以实现对高并发请求的支持。
缺点:需要修改的代码较多,涉及到Session的地方都需要更改。不太适合对老系统的改造,比较适合于新开发的系统。但是如果我们提前将用户接口抽离成了一个单独的服务,那么改造起来还是比较好处理的。