单点登录

用户只需要登录一次就可以访问所有相互信任的应用系统。

讲登录的session信息不是单独放到某台服务器,而是放到一个redis数据库中,从redis查询session判断是否已经登录。或者实现session共享,讲session信息放到memcached缓存中。

以前的登录流程

在系统服务器只有一个的时候,登录后的客户信息一般是存在服务器的session域对象中,通过sessionId进行存取或者其他操作。

当用户通过客户端访问我们的系统的时候,用户通过我们的商城系统首页输入用户登录信息。然后表现层(controller)去调用我们的业务逻辑层(service)业务逻辑层通过调用持久层(dao)得到的数据从数据库中取得相应的用户数据。然后将表现层和持久层的数据进行对比,判断是否登录成功。

如果成功,将信息保存在当前服务器的session中,然后将登录成功的数据返回给客户。如果登录失败,则是直接将失败信息返回给客户。

而在访问的时候,用户通过sessionId冲session中获取用户的商品详情。流程如图:

集群登录分析

之前的登录方式,在服务器只有一台的时候,是没有问题的。但是,每个服务器可以承受的访问量是有限制的。这个时候,我们就需要用多个服务器撘一个集群,共同为我们的商城提供服务。

那么问题来了。这么多台服务器同时提供服务,很有可能用户第一个请求发送到了服务器1,第二个请求就发送到了服务器2。请求具体会分配到哪个服务器是随机的。这时就会涉及这么个问题:如果登录的请求发送到了第一个服务器上,那么,用户的登录信息就会存在第一个服务器的session上。第二个请求,假如说是用户在下单的话,带着的那个sessionId从服务器2中就没有办法找到我们的session信息。那么,经过业务逻辑层判断时,就会判定,该用户是没有登录的,让用户再次重新登录。如图所示:

对此,我们有两个解决方案:方案一,如果搭建的集群中服务器并不多的话,就将服务器中的session进行共享。服务器会在局域网内进行广播,这个时候,如果局域网内中的服务器过多的话,服务器需要拿出很多的资源用来做session的同步。这样的话,集群数量的增多反而会降低集群整体处理请求的效率。所以,该方案适用于服务器低于5台以下的集群。

方案二:不再将用户的信息放在session中。而是将session信息放在系统的redis缓存中。由redis实现session的相应的功能。使用redis实现session的功能的原理图如下:

 

(两个redis其实是一个数据库,这里这样画室为了简洁)

当用户登录的时候,依然是输入用户名和密码。然后表现层将数据将数据传入单点登录系统,由单点登录系统从数据库中将数据取出,然后判断用户是否登录成功。如果登录成功,生成一个类似于sessionId的东西,我们称之为ticket。然后以ticket为redis的键,用户的数据作为值。存入redis服务器,并且将登录成功的信息和ticket一起返回给用户的浏览器,将这个信息写入用户的cookie。

用户在访问的时候,先根据用户的ticket信息从redis服务器中查询用户的信息,如果查询到,则跳转到服务器,为用户提供服务,如果用户没有登录,则直接跳转到登录界面。

注:图片均取自其他老师,非本人自己画的。

 

posted @ 2017-02-14 16:26  上台阶  阅读(238)  评论(0编辑  收藏  举报