您的位置:首页 > 编程语言 > Java开发

spring boot高性能实现二维码扫码登录(下)——订阅与发布机制版

2018-03-26 15:35 597 查看

 前言

 

  基于之前两篇(《spring boot高性能实现二维码扫码登录(上)——单服务器版》和《spring boot高性能实现二维码扫码登录(中)——Redis版》)的基础,我们使用消息队列的订阅与发布来实现二维码扫码登录的效果。

 

一、实现原理

 

1.参考微信的二维码登录机制

首先,请求后端拿到二维码。然后通过http长连接请求后端,并获取登录认证信息。这时,当二维码被扫,则记录seesion并跳转至内部页面。

如果没有扫码二维码,则线程会等到30秒(也有的说是20秒),如果再此期间,二维码被扫,则唤醒线程。如果二维码没有被扫,并且30秒等待结束,则前端页面再次请求服务器。

2.线程等待机制

我使用CountDownLatch来控制线程的等待和唤醒。控制器返回Callable<>对象来达到“非阻塞”的目的。

3.订阅与广播机制

参考:https://spring.io/guides/gs/messaging-redis/

使用redis的消息队列机制,当然使用别的中间件来做消息队列是可以的。这里是为了演示方便才使用redis,时间项目中我很少用redis做消息队列。

使用单例模式存储一个Map<>对象,用于保存登录状态。当在30秒内请求不到被扫的结果,则阻塞线程。当二维码被扫后,通过redis发送广播,当其中后端服务器(可以是多台服务器)接收到广播后,唤醒被请求的那台服务器的线程。

 

 

二、代码编写

 

 

package com.demo.auth;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {

public static void main(String[] args) {
SpringApplication.run(App.class, args);
}

}
App.java

 

 

三、运行效果

 

如下图所示,请求后台,如果没有扫码结果,则等待30秒:

 

如果30后,二维码依然没有被扫,则返回http状态200的相应。前端则需再次发起请求:

 

 如果长时间不扫(5分钟),则刷新二维码。

 

 

 

 整个流程的运行效果如下图所示:

 

 

 

总结

 

  使用Redis作为消息队列的目的是,发送和接受消息订阅。当然,如果是正式项目您最好使用性能高的消息队列中间件,我这里使用Redis是为了演示方便而已。

那么为什么要使用消息队列的订阅和广播呢?那是因为,如果有多台服务器,其中一台“对等”的服务器内存中里存储了登录的CountDownLatch来阻塞线程,而APP端扫码又访问了其他“对等”的服务器,如果不使用“广播机制”,那么阻塞线程的服务器就不会被唤醒,除非APP的请求刚好访问到被阻塞的那天服务器。

 

好了,关于扫码登录的博客就写完了。如果我这几篇博客中有不完善的地方或者是没有考虑到的地方,欢迎大家留言,谢谢。

 

 

 

代码下载

 

如果你觉得我的博客对你有帮助,可以给我点儿打赏,左侧微信,右侧支付宝。

有可能就是你的一点打赏会让我的博客写的更好:)

 

返回玩转spring boot系列目录

 

           
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: