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

  基于之前两篇(《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发送广播,当其中后端服务器(可以是多台服务器)接收到广播后,唤醒被请求的那台服务器的线程。

 

 

二、代码编写

 

 

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

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

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 "> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>auth</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>auth</name> <description>二维码登录</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- zxing --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.3.0</version> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- session --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zydgdy.html