微服务系列之-分布式Session安全认证


前言

这篇博客的目的是为了研究session会话在微服务架构中采用的技术方案,以及探讨一下企业应用在使用session过程中需要注意的问题。


一、session作用

我们知道在web应用中,web服务器和浏览器之间是用http协议进行通信的,而http协议是无状态的,也就是每个请求都是独立的。如:用户看一条A新闻,不管是谁看到的都是一模一样的新闻。也就是跟用户是谁没有任何关系。

但业务自身的发展,需要把不同的内容展示给不同的用户,即信息和用户状态关联起来。如:历史阅读列表—列出用户之前看的新闻。这个需求就是跟用户相关,每个用户看到的历史阅读列表都是不一样的。

Session的产生就是为了解决这个问题,把服务器和客户端之间进行状态保持的解决方案。

二、session原理

浏览器在第一次访问web服务器,服务器端会响应一个sessionId,并且把这个sessionId传输给浏览器,并以cookie保存sessionId到浏览器本地。

以后的访问会把这个cookie的sessionId以请求头的方式传给服务器,这样服务器就可以拿着这个sessionId进行查找,服务器中有没有此sessionId对应的用户,这样就能标识出哪个用户,如果有用户相关的业务,就是利用这个sessionId返回用户相关的业务。如下图:

在这里插入图片描述
本质就是浏览器客户端本地保存了sessionId,服务器端保存了sessionId和用户信息映射,这样就实现了web应用有状态化。

三、单体架构


在这里插入图片描述
在早期的单体架构中,也就是只有一台web服务器,虽然在web应用中也进行的分层设计,但其实本质是在代码逻辑级别,本身还是一个应用而已(或者说就是一个war/jar包)。

这个时期的session都是保存在本地的web服务器内存中,非常简单就能保持用户状态。

四、集群/分布式架构

随着业务的复杂度升高,和对应用性能、高可用的需求,系统演变成了集群和分布式架构。

在这里插入图片描述
集群架构可以看服务器A和服务器B,部署同一个应用,就是为了提升性能和高可用目的;服务器C是部署了另一个应用A,代表系统不是单一业务,而是多个应用集合的,即分布式架构。

这个架构中,我们之前的session方案就会有问题,因为服务器端的session是存放在本地内存中的。请看下面的流程

  1. 用户A第一次访问系统,由负载均衡器映射到服务器A中
  2. 会在服务器A的本地内存中,存放着session
  3. 用户A第二次访问系统,又被随机分配到了服务器B中
  4. 但服务器B中是没有存放用户A的session的,所以此sessionId在服务器B中找不到对应的session,就会以为用户没有登录,就会引导用户去登录
  5. 这样就导致session不一致的问题。

五、Session复制

session复制方案是一个服务器端的方案,对客户端是透明的,客户端不需要改变什么。看架构图
在这里插入图片描述
这个方案本质是利用了应用服务器自身的特性,如:tomcat。修改一下tomcat的配置文件,就是让应用服务器之间进行session复制,这样就可以达到每个服务器都有一样的session。

这个方案2-3个服务器还行,但服务器一旦多起来,就会有问题。

  1. session之间的复制就会占用很大的网络带宽
  2. session复制是有时间延迟的
  3. 服务器的内存是有限的,代表着session存放是有限的

六、Session粘性

这个方案就利用负载均衡器的特性,把同一个浏览器的同一个用户都定向发送到同一个服务器上。看架构图
在这里插入图片描述
上图的核心思路,用户甲访问系统被负载均衡器一直分配到服务器A上,这样也就保证了用户一直在同一个服务器中进行查找session,保证了用户session一致性。

不过此方案也存在一些问题:

  1. 服务器的内存是有限的,代表着session存放是有限的
  2. 这个方案适用集群架构,但不适用分布式架构
  3. 一旦服务器拓展数量,session就会出现混乱

七、Cookie方案

之前的方案都是在服务器端进行改造的,cookie方案是客户端的方案,就是把session信息保存到cookie中,即用户信息保存到cookie中,这样就不需要服务器保存session(用户信息)了。每次请求时,把此cookie传给服务器端,这样服务器端就知道是哪个用户了。

此方案比较实现比较简单,而且还不占用服务器端的内存资源。但是此方案的问题很大哦。

  1. cookie在客户端是有限的,存储容量也是很小的
  2. 安全是很有问题的,因为保存在本地,很容易被人拿到

八、Session外部存储

之前的服务器端改造的方案,session都是存储到本地内存中的,导致一些问题。此外部存储就是把思路进行改变,让session的存储与应用服务器隔离出来,看架构图
在这里插入图片描述

数据库存储

存储媒介的选择之一就是数据库,就是把session信息存储到数据库中。

好处就是session持久化到数据库中,不会丢失。但性能比较差,因为session的访问是非常频繁的,会对数据库造成很大压力,

Memcache存储

此方案就是把session存储到memcache中,Memcache-Tomcat-Session就是利用tomcat实现session的集中化管理的开源方案,修改tomcat配置就行了,使用扩展的sessionManager替换tomcat默认的Session管理器。
在这里插入图片描述

memcache性能比较高,但此方案和tomcat强耦合了,不适合其他的应用服务器,如:jetty。而且memcache无持久化,一旦重启,session就丢失了。

Redis存储

redis存储方案一般结合spring session方式,把session存储到redis中。
在这里插入图片描述

这个方案是spring提供的一套Session管理方案,通过一个SessionFilter将所有请求拦截下来,对session进行管理,此方案的好处就是不与应用服务器耦合,可以部署到任何web应用服务器中。redis也是高性能的缓存服务器,且可持久化。这个方案也是官方推荐的。

总结

在面试的时候可能会经常遇到一个问题就是:分布式Session如何实现?

  • 我们可以把session统一放在redis服务器里面进行管理。
  • 可以使用springsession和redis对session进行统一的管理。

为什么要spring-session?

  • 传统的Tomcat、Jetty等web容器当中,用户的session都是由容器进行统一的管理的。
  • 但是这样的架构面对现在的分布式的时候有点力不从心了。因为现在的用户请求可能被负载分发到不同的服务器上面了。

spring-session

  • spring-session的核心思想在于此:将session从web容器中剥离,存储在独立的存储服务器中。
  • 目前支持多种形式的session存储器:Redis、Database、MogonDB等。
  • session的管理责任委托给spring-session承担。
  • 当request进入web容器,根据request获取session时,由spring-session负责存存储器中获取session,如果存在则返回,如果不存在则创建并持久化至存储器中。
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页