google的api key调用次数是多少_Sprint Boot如何基于Redis发布订阅实现异步消息系统的同步调用?...

8fd4c123c7fa28f14a5ad570c9e66fe5.png

前言

在很多互联网应用系统中,请求处理异步化是提升系统性能一种常用的手段,而基于消息系统的异步处理由于具备高可靠性、高吞吐量的特点,因而在并发请求量比较高的互联网系统中被广泛应用。与此同时,这种方案也带来了调用链路处理上的问题,因为大部分应用请求都会要求同步响应实时处理结果,而由于请求的处理过程已经通过消息异步解耦,所以整个调用链路就变成了异步链路,此时请求链路的发起者如何同步拿到响应结果,就需要进行额外的系统设计考虑。

为了更清晰地理解这个问题,小码哥以最近正在做的共享单车的IOT系统为例,给大家来一张图描述下,如图所示:

bee4a5d5139fc0331f8be66eab2630ef.png

在上述系统流程中,终端设备与服务端之间通过MQTT协议相连,而MQTT协议本质上是一种异步消息的连接方式,因此业务应用(如图中的订单系统)发起开锁请求后,IOT应用系统会以MQTT协议的方式通过物联网平台(此处使用的是AWS IOT服务)向设备发起开锁下行消息,而这一过程在IOT应用系统完成与物联网平台的交互后同步调用链路就结束了,因为物联网平台与锁设备之间通过MQTT消息服务异步解耦了,当然物联网平台会通过一系列可靠消息机制来确保开锁消息能够发送到指定设备的监听MQTT队列。而至于锁设备是否能够及时接收到开锁下行MQTT消息,则取决于锁设备当时的移动网络情况。

锁设备在收到MQTT开锁消息后,会通过嵌入式软件系统触发硬件设备完成开锁动作,之后就需要通过MQTT上行消息将开锁结果反馈到服务端,从而由服务端系统判断是否创建骑行订单并计算费用。这一过程需要物联网平台监听指定锁设备相应的MQTT上行消息队列,由于物联网平台需要与上万个设备进行连接,因而不可能将每一个锁设备所产生的MQTT上行消息都直接转发给Iot应用系统,因此在物联网平台可以将一类的设备MQTT消息转发至特定的业务消息队列中,例如开锁上行消息,所有设备的MQTT开锁响应上行消息都可以转发到表示开锁响应的Iot业务消息队列,如“iot_upstream_lock_response”,这样Iot业务系统则不需要再关注底层设备的MQTT消息,可以用更利于业务理解的方式去处理开锁响应结果。

现在的问题是通过MQTT协议的开锁下行消息、上行消息已经完全处于两条不同的异步网络链路,而链路的发起者此时却需要同步等待开锁结果,但是实际上同步链路早已在Iot应用系统向物联网平台发送开锁消息后就已经完成,所以为了满足调用方的同步请求/响应需要就需要在Iot应用系统的下发开锁消息后进行额外的同步阻塞等待,并监听开锁响应的Iot业务消息队列“iot_upstream_lock_response”关于此次开锁请求的上行消息,之后再结束掉之前的同步阻塞等待逻辑,从而实现向业务调用方返回实时开锁响应结果的同步调用效果。那么在上述流程中如何实施额外的同步阻塞以及如何进行回调消息的监听呢?在接下来的内容中就和大家一起探讨具体的实施方案!

解决方案分析

以上问题在使用消息服务进行异步解耦的应用场景中是比较普遍的需求,由于异步调用链路非常长所以通用的解决思路是在调用链的起始端进行同步阻塞,而在调用链的结束端通过回调的方式来实现,如下图所示:

ce277079a2c9d805cd14e262ed80eedc.png

在上述图示中,链路起始队列处在发送第一次异步消息后会开启一个临时队列并同步阻塞监听该临时队列的回调消息,而链路的结束队列在完成逻辑处理后需要回调起始队列监听的临时队列,而由于请求线程一直处于阻塞监听该临时队列的状态,所以一旦收到回调消息就可以结束阻塞执行后续流程,从而完成整个链路的同步响应。
虽然常见的消息中间件都可以实现以上逻辑,例如小码哥之前所在的公司就基于RabbitMQ通过临时队列的方式实现过消息链路的同步调用,但是基于消息中间件的方式多少还是显得有些繁琐,对于常见的消息中间件如RocketMQ、RabbitMQ来说异步消息才是其强项,如果以大量临时队列的创建和销毁为代价来实现消息调用链路的同步,不仅从使用上来说显得有些麻烦,并且也会对消息中间件的稳定性带来一些不好的影响。

因此在前面提到的IOT系统中,我们采用了基于Redis的发布/订阅功能来实现异步消息链路的同步化调用。而由于Redis的高性能以及Redis的应用场景非常丰富,并且非常适合数据频繁变动的场景,在系统中既可以作为NoSQL数据库来使用,同时还支持分布式锁等功能,因而维护的性价比也相对较高。接下来我们就基于Spring Boot的开发框架来演示如何利用Redis的发布/订阅来实现异步消息链路的同步回调!

Redis发布订阅机制

Redis本身可以通过发布订阅机制实现一定的消息队列功能,在Redis中通过subscribe/publish等命令可以实现发布订阅功能,基于此原先的IOT系统处理示意图如下:

2c42e0e98ad5924bace607281a1970b3.png

如上图所示,在IOT应用端发送异步MQTT消息后会以消息ID组成的Key作为频道****,并保持请求线程对该频道的同步监听,直到收到Iot业务消息队列的开锁结果上行消息后,在消息队列的消费端将该上行消息发布至同样以消息requestId组成的频道中,从而实现基于Redis发布订阅机制的异步消息系统同步调用效果。

Spring Boot代码实现

下面我们基于Spring Boot演示如何通过代码进行实现,创建Spring Boot工程后引入Spring Boot Redis集成依赖包,如下:

<!--

之后在项目的配置文件中添加Redis服务连接信息,如下所示:

spring:

此时项目就具备了访问Redis的能力,接下来我们通过具体的代码实现来进行功能演示。订阅监听代码如下:

@RestController

在上述代码中,我们模拟了一个开锁请求,在完成异步消息处理后会开启Redis订阅监听,为了实现异步阻塞还需要我们创建消息任务对象,代码如下:

public 

在消息任务对象中我们通过JDK1.8新提供的CompletableFuture类实现线程阻塞效果,并通过定义消息监听对象及超时时间完善处理机制。此外根据Controller层代码还需要自定义定义消息监听处理对象,代码如下:

public 

此时就完成了Redis服务订阅这部分逻辑的编写,在后续的逻辑处理中需要完成消息的发布才能正常结束此处的阻塞等待,接下来我们写一段代码来模拟消息发布,代码如下:

@RestController

此时启动Spring Boot应用调用开锁模拟接口,逻辑就会暂时处于订阅等待状态;之后再模拟调用开锁回调Redis消息发布逻辑,之前的阻塞等待就会因为监听回调而完成同步返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

加密、解密以及Openssl建立私有CA

一、openssl简介 OpenSSL 是一个强大的安全套接字层密码库&#xff0c;囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议&#xff0c;并提供丰富的应用程序供测试或其它目的使用。 SSL:secure socket layer 安全套接层协议 可以在internet提供秘密性的传输。…

密西根州立大学计算机qs分数,2020年QS世界大学排名密歇根州立大学排名第144

2020年QS世界大学排名指标1.Academic Reputation 学术声誉(所占比重为40%)这项指标数据来源于QS学术调查。搜集了80,000多位高校领域大牛对教学和科研方面的意见。这也是世界上类似调查中规模最大&#xff0c;覆盖面最广的。2.Employer Reputation 雇主声誉(所占比重为10%)考察…

全球2%高智商天才必测脑力题!却只有1%的人,能在5分钟内全部做对!

▲ 点击查看说起娱乐圈最“变态”的养娃爸爸&#xff0c;妥妥非吴尊莫属&#xff01;上亿元的学区别墅、几十万学费1年的文莱国际幼儿园、一周7天辅导班、家教、每年1个儿童国际比赛、考证拿奖……1个吴尊绝对抵得上8个海淀妈。前段时间吴尊晒出neinei二年级毕业成绩单&#xf…

IBM软件OEM概览

http://files.cnblogs.com/menghe/IBM%E8%BD%AF%E4%BB%B6OEM%E6%A6%82%E8%A7%88.pdfmenghecn.ibm.com 转载于:https://www.cnblogs.com/menghe/archive/2012/01/26/2329712.html

如何优化 .NET Core 中的 lambda 查询表达式 ?

咨询区 Moutia AYED&#xff1a;我的项目需要构建几个图表&#xff0c;产生图表的 数据源 相对比较复杂&#xff0c;参考如下代码:var resultdb await _dbContext.TimeSheetElements.Where(t > t.UserId userId &&t.Date.Month month && t.Date.Year y…

asp.net中gridview 如果字数太多可以用此方法把字体变短+.....

首先启动一个RowDataBound控件里面在加上一个if ((e.Row.Cells[0].Text).Length > 6) { e.Row.Cells[0].Text (e.Row.Cells[0].Text).Substring(0, 6) "…";//截取文章主题 }//如果是第一列的话用cell【0】 if ((e.Row.Cells[1].Text).Length…

python数据整理_python数据类型整理

Python中常见的数据结构可以统称为容器&#xff08;container&#xff09;。序列&#xff08;如列表和元组&#xff09;、映射&#xff08;如字典&#xff09;以及集合&#xff08;set&#xff09;是三类主要的容器。 一、序列&#xff08;列表、元组和字符串&#xff09; 序列…

爬取三千条数据需要多久_存储-性能,IOPS,带宽,吞吐量,1TB数据需要多久写完...

让我们先看一下这三个概念&#xff1a;IOPS (Input/Output Per Second) 即每秒的输入输出量(或读写次数)&#xff0c;是衡量存储介质性能的主要指标之一。IOPS是指每秒钟系统能处理的读写请求数量。 吞吐量&#xff08;Throughput &#xff09;衡量的是存储介质的数据传输速率&…

TortoiseSVN客户端重新设置用户名和密码[转]

在第一次使用TortoiseSVN从服务器CheckOut的时候&#xff0c;会要求输入用户名和密码&#xff0c;这时输入框下面有个选项是保存认证信息&#xff0c;如果选了这个选项&#xff0c;那么以后就不用每次都输入一遍用户名密码了。 不过&#xff0c;如果后来在服务器端修改了用户名…

这就是你们有钱人炫富的新方式吗?

1 真正的1秒可爱喷雾▼2 你们父子俩的脚咋回事啊&#xff1f;▼3 咦&#xff1f;影子动了&#xff01;▼4 小姐姐&#xff0c;你这样就很过分了&#xff01;▼5 宝宝发现了一个新玩具▼6 这就是有钱人炫富的新方式吗&#xff1f;▼7 单身久了&#xff0c;看两片茶叶转圈…

最新服务器处理器天梯,服务器CPU性能排行榜天梯图(双路/三路/四路)

排名多路处理器CPU性能分1[四路] Intel Xeon Platinum 8180 2.50GHz441392[双路] Intel Xeon Gold 6154 3.00GHz359483[双路] Intel Xeon Gold 6138 2.00GHz356594[双路] Intel Xeon Gold 6152 2.10GHz353685[双路] Intel Xeon E5-2699 v4 2.20GHz343306[双路] Intel Xeon…

centos 下 mysql 主从库搭建

作者:蘑菇 今天在本本上装了个mysql主从库配置&#xff0c;中间遇到了几个问题&#xff0c;不过经过搜寻资料&#xff0c;已经可以正常工作了。 过程写下来做个记录&#xff1a; 因为上次已经装过LNMP&#xff0c;所以只要再装一个mysql做从库就好了。重新编译mysql安装$ tar …

Dapr + .NET 实战(五)Actor

什么是Actor模式Actors 为最低级别的“计算单元”以上解释来自官方文档&#xff0c;看起来“晦涩难懂”。大白话就是说Actors模式是一段需要单线程执行的代码块。实际开发中我们经常会有一些逻辑不能并发执行&#xff0c;我们常用的做法就是加锁&#xff0c;例如&#xff1a;lo…

打印机一直显示正在打印中_中国和桌面3D打印机正在引领3D打印市场

2020年11月4日&#xff0c;南极熊获悉&#xff0c;国外的市场研究公司CONTEXT最近发布了3D打印市场报告&#xff0c;“中国”和“桌面3D打印机”正引领全球的3D打印市场从COVID-19疫情中复苏。分析报告显示&#xff0c;在2020年第一季度至第二季度期间&#xff0c;中国国内工业…

python中的星号和乘号_Python 函数中参数前面一个和两个星号(**)的区别

Python是一种计算机程序设计语言。是一种面向对象的动态类型语言&#xff0c;最初被设计用于编写自动化 脚本( shell)&#xff0c;随着版本的不断更新和语言新功能的添加&#xff0c;越来越多被用于独立的、大型项目的开发。在 Python 的函数中经常能看到输入的参数前面有一个或…

sql重新注册服务器,sql server无法新建注册服务器怎么办?

SQL Server 不存在或访问被拒绝ConnectionOpen (Connect())这个"SQL Server 不存在或访问被拒绝"通常是最复杂的&#xff0c;错误发生的原因比较多&#xff0c;需要检查的方面也比较多。一般说来&#xff0c;有以下几种可能性&#xff1a;1、SQL Server名称或IP地址拼…

java中的递归

所谓递归&#xff0c;是指程序调用自身&#xff0c;当然&#xff0c;递归不会无休止地调用下去&#xff0c;它必然有一个出口&#xff0c;当满足条件时程序也就结束了&#xff0c;不然的话&#xff0c;那就是死循环了。看下面这个类&#xff0c;有几个递归方法&#xff0c;看了…

雨中的蚊子为啥不会被雨滴砸死?

全世界只有3.14 % 的人关注了爆炸吧知识在细雨中漫步是很浪漫的一件事&#xff0c;但作为蚊子&#xff0c;雨中飞行相当于天上掉汽车&#xff01;你有没有想过&#xff0c;它们是怎么活下来的&#xff1f;直到2015年&#xff0c;菠萝科学奖物理学奖颁给美国佐治亚理工学院胡立德…

.NET 6 迁移到 Minimal API

.NET 6 迁移到 Minimal APIIntro上次写了一篇 Minimal API Todo Sample&#xff0c;有些童鞋觉得 Minimal API 有些鸡肋&#xff0c;有一些功能的支持都不太好&#xff0c;但是其实 Host 之前支持的功能 Minimal API 大部分都是支持的&#xff0c;上次的 Todo Sample 完全没有使…

教你透彻了解红黑树

教你透彻了解红黑树 作者&#xff1a;July、saturnman 2010年12月29日本文参考&#xff1a;Google、算法导论、STL源码剖析、计算机程序设计艺术。本人声明&#xff1a;个人原创&#xff0c;转载请注明出处。推荐阅读&#xff1a;Left-Leaning Red-Black Trees, Dagstuhl Wor…