RabbitMQ高阶使用消息推送

目录

  • 1 从打车开始说起
    • 1.1 需要解决的问题
    • 1.2 消息推送
  • 2 消息推送
    • 2.1 什么是消息推送
    • 2.2 方案介绍
      • 2.2.1 ajax短轮询
      • 2.2.2 长轮询
      • 2.2.3 WebSocket
    • 2.3 WS实现消息推送
      • 2.3.1 架构介绍
      • 2.3.2 暂存数据
        • 2.3.2.1 什么是MongoDB
        • 2.3.2.2 插入数据
        • 2.3.2.3 查询数据
      • 2.4.1 轮询任务
        • 2.4.1.1 代码实现


1 从打车开始说起

在这里插入图片描述

在这里插入图片描述

我们把滴滴打车的流程简化下

在这里插入图片描述

  1. 登录app后点击打车开始进行打车
  2. 打车服务开始为司机派单
  3. 司机接单后开始给来接驾
  4. 上车乘客后处于行程中
  5. 行程结束后完成本次打车服务

1.1 需要解决的问题

我们需要实现派单服务,用户发送打车订单后需要进行进行派单,如果在指定时间内没有找到司机就会收到派单超时的通知,并且能够实时查看当前排队的抢单人数

在这里插入图片描述

下面我们来介绍下涉打车涉及到的一些问题

1.2 消息推送

我们需要将我们的异步处理结构返回到客户端,我们的客户端是使用的websocket连接的,因为websocket是点对点连接的,连接到一台固定的通知服务后,只能从这一台通知服务来获取数据,因为我们的通知服务允许分布式部署,这个问题改如何解决?

在这里插入图片描述

2 消息推送

2.1 什么是消息推送

当我们使用http协议探知服务器上是否有内容更新,就必须频繁的从客户端到服务器端进行确认,而http一下的这些标准会成为一个瓶颈:

  • 一条连接上只可以发送一个请求
  • 请求只能从客户端开始,客户端不可以接收除了响应以外的指令
  • 请求 / 响应首部未经过压缩就直接进行传输,首部的信息越多,那么延迟就越大。
  • 发送冗长的首部,每次互相发送相同的首部造成的浪费越多
  • 可以任意选择数据压缩格式,非强制压缩发送

2.2 方案介绍

2.2.1 ajax短轮询

Ajax(异步的javascript与xml技术)是一种有效利用javascript和dom的操作,以达到局部web页面的提花和加载的异步通信手段,和以前的同步通信相比,他只更新一部分页面,相应中传输饿数据量会因此的减少

在这里插入图片描述

Ajax轮询的原理是,让浏览器每隔一段时间就发送一次请求,询问服务器是否有新消息,而利用ajax实时的从服务器获取内容,有可能导致大量的请求产生。

	特点:实现简单、短连接、数据同步不及时、对服务器资源会造成一定压力,此模式广泛应用于:扫描登录、扫码支付、天气更新等(腾讯、京东、阿里一直都在沿用此技术并日渐成熟和稳定)

2.2.2 长轮询

原理和Ajax轮询差不多,都是采用轮询的方式,不过采用的是阻塞模型

在这里插入图片描述

	也就是说,当客户端发起连接后,如果服务器端内容没有更新,将响应至于挂起状态,一直不回复response给客户端,知道有内容更新,再返回响应。

	虽然可以做到实时更新,但是为了保留响应,一次连接饿持续时间也变长了,期间为了维持连接会消费更多的资源,需要有很高的并发,也就是说同时接待客户的能力

	从上面两种方式中,其实可以看出是再不断的建立http连接,然后等待服务器处理,可以体现出了http的特点:**被动性**,即:请求只能由客户端发起,服务器端不能主动联系客户端。

	特点:无需浏览器或APP端任何单独插件支持、长连接,减少网络(三次)握手和四次挥手、对服务器资源要求较高等,此模式常用于实时消息轮播、金融数据即时刷新、数据图表实时刷新等,JAVA服务器端一般采用Servlet3支持的异步任务、延时结果(DeferedResult)等手段实现。

2.2.3 WebSocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议

	WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

在这里插入图片描述

2.3 WS实现消息推送

通过上面我们实现了延时任务处理以及派单排队,但是如果将我们的异步处理结果推送给客户端呢

我们就需要使用消息推送技术,需要完成一下功能

  • 将消息推送到指定的用户
  • 对于未上线用户需要暂存数据,上线后推送

在这里插入图片描述

2.3.1 架构介绍

因为websocket是点对点的,而服务间调用是轮询的,无法实现微服务之间点对点的消息推送,我们使用定时任务来实现消息推送

在这里插入图片描述

  1. 调用接口先将消息暂存到MongoDB中
  2. 轮询任务首先拉取当前在线人员列表
  3. 轮询任务通过在线人员列表到MongoDB中拉取在线用户的通知消息
  4. 将消息通过WS推送到指定的用户

2.3.2 暂存数据

通过MongoDB将我们的消息数据暂存到数据库中,可以完成对于未上线消息暂存以及对分布式websocket的数据调度

2.3.2.1 什么是MongoDB

	MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

2.3.2.2 插入数据

@Override
public void addMessage(PushMessage message) {
    mongoTemplate.save(message);
}

2.3.2.3 查询数据

@Override
public List<PushMessage> getMessageByUserNames(List<String> userNameList) {
    Query query = new Query(Criteria.where("username").in(userNameList));
    return mongoTemplate.findAllAndRemove(query, PushMessage.class);
}

2.4.1 轮询任务

轮询任务就是不断的搜索检查是否有新的消息,然后交给WS进行处理

在这里插入图片描述

2.4.1.1 代码实现

使用pull方式将MongoDB中的在线用户的暂存消息取出来,推送给在线用户


/**
 * 定时任务 推送暂存消息
 */
@Component
public class ScheduledTask {

    private static final Logger logger = LoggerFactory.getLogger(ScheduledTask.class);

    @Autowired
    private PushService pushService;

    private static final ExecutorService executorService = Executors.newFixedThreadPool(10);

    @Autowired
    private WebSocketServer webSocketServer;

    @PostConstruct
    public void init() {
        executorService.execute(() -> {
            autoPushMessage();
        });

    }


    /**
     * 自动推送消息
     */
    public void autoPushMessage() {
        //轮询并发送消息
        PollingRound.pollingPull(() -> {
            //获取最新需要推送的消息
            List<PushMessagePO> pushMessagesList = getPushMessages();
            //校验消息
            if (null != pushMessagesList && !pushMessagesList.isEmpty()) {
                logger.debug("推送消息线程工作工作中,推送数据条数:{}", pushMessagesList.size());
                //推送消息
                webSocketServer.pushMessage(pushMessagesList);
                return PollingRound.delayLoop(100);
            }
            logger.debug("推送消息线程工作工作中,推送数据条数:{}", 0);
            return PollingRound.delayLoop(1000);
        });
    }

    public List<PushMessagePO> getPushMessages() {
        List<String> userNameList = webSocketServer.getInLineAccountIds();
        if (null != userNameList && !userNameList.isEmpty()) {
            //在MongoDB中获取当前在线用户的暂存消息
            List<PushMessagePO> pushMessageList = pushService.getMessageByAccountIds(userNameList);
            //返回消息
            return pushMessageList;
        }
        return null;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

软件工程导论期末急救包(上)

目录 什么是软件工程&#xff1f;它的目标和内容是什么&#xff1f; 软件文档作用及包含 软件过程模型 瀑布模型 快速原型模型 增量模型 螺旋模型 喷泉模型 软件生存周期 需求分析阶段的基本任务是什么&#xff1f; 可行性研究的任务是什么&#xff1f; 软件是什…

vue+el-select下拉实现:全选、反选、清空功能

问题描述&#xff1a; el-select下拉框要求实现全选功能。具体功能包括&#xff1a; 当选择【全选】时&#xff0c;所有选项全部被勾选&#xff1b;当选择【反选】时&#xff0c;已选择选项变为未选择选项&#xff0c;未选项变为已选项当选择【清空】时&#xff0c;所有选项变…

带你用Python制作7个程序,让你感受到端午节的快乐

名字&#xff1a;阿玥的小东东 学习&#xff1a;Python、C/C 主页链接&#xff1a;阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 前言 程序1&#xff1a;制作粽子 程序2&#xff1a;龙舟比赛 程序3&#xff1a;艾草挂 程序4…

【人脸检测0】视频分解图片与图片合成视频

一,引言 目标:这小节主要通过两个demo熟悉视频分解图片与图片合成视频的OpenCV的应用 环境:python3.6+OpenCV3.3.1 二,示例 Demo1:视频分解图片 目标: 1.指定文件夹中读取视频文件 2.将视频文件分解为图片 3.将图片保存在指定文件夹中 # -*-coding:utf-8-*- #auth…

澳洲学生用ChatGPT代写?澳洲多所高校使用全新反击工具检测

朋友们听句劝 ChatGPT可太危险了 ChatGPT有多火&#xff1f;据2月1日瑞银发布的一项研究报告显示&#xff0c;仅仅发布两个月&#xff0c;ChatGPT月活跃用户已达1亿&#xff0c;这是历史上增长速度最快的应用。要知道达成1亿用户的时间&#xff0c;Instagram用了2.5年&#xf…

合宙Air724UG Cat.1模块硬件设计指南--SDIO接口

SDIO接口 简介 SDIO(Secure Digital Input and Output)全称为安全数字输入输出接口&#xff0c;在协议上和SPI类似是一种串行的硬件接口&#xff0c;通信的双方一个作为HOST&#xff0c;另一端是Device&#xff0c;所有的通信都是由HOST端发送命令开始的&#xff0c;Device端只…

Stable Diffusion实操示例

一、负向提示词 解决问题&#xff1a;生成的图片存在瑕疵&#xff0c;比如多只眼睛、多只手指等情况。通过embeddings可以避免一些常用的不好结果。 方法&#xff1a;从https://civitai.com/?utm_sourcenettsz.com 中下载负向提示词的embeddings模型&#xff0c; EasyNegat…

广角积分球均匀光源

现阶段&#xff0c;摄影测量技术已涉及多行多业&#xff0c;其在交通、考古以及景物三维重建中的应用尤为显著&#xff0c;但是普通相机取景范围有限&#xff0c;不能全面捕获整个空间信息&#xff0c;因此一种新型相机--全景相机逐步被应用到实际当中。80年代初&#xff0c;国…

R语言 tidyverse系列学习笔记(系列5)dplyr 数据分析之across

成绩单 score install.packages("dplyr") library(dplyr)install.packages("tibble") library(tibble)install.packages("stringr") library(stringr)score tibble(IDc("1222-1","2001-0","3321-1","4898-…

MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

STM32-I2C通信在AT24C02的应用

AT24C02是一种失去电源供给后依旧能保持数据的储存器&#xff0c;常用来储存一些配置信息&#xff0c;在系统重新上电之后也可以加载。它的容量是2k bit的EEPROM存储器&#xff0c;采用I2C通信方式。 AT24C02支持两种写操作&#xff1a;字节写操作和页写操作。本实验中我们采用…

数据结构算法 -分而治之算法

引言 坤坤是一个养鸡场的员工&#xff0c;他非常热爱他的工作&#xff0c;并且总是努力提高他的专业技能。有一天&#xff0c;养鸡场接到了一项任务&#xff1a;在短时间内处理一批大量的鸡。 这批鸡数量非常大&#xff0c;比普通的数量要多得多&#xff0c;坤坤意识到他们需…

C++核心编程——详解函数模板

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.模板的基础知识①为什么有模板&#xff1f;②初识模板 二.函数模板①函数模板的定义②函数模板的使用③函数模板实例化1️⃣隐式实例化2️⃣显…

泰坦陨落2找不到msvcr120.dll的解决方法

msvcr120.dll是的动态链接库文件之一。它在Windows操作系统中发挥着重要的作用&#xff0c;它提供了应用程序所需的各种功能和方法。 该文件返回编译后的代码所需的支持库。msvcr120.dll包含用于C / C编译器生成的应用程序所需的重要功能&#xff0c;包括数学函数&#xff0c;…

C++学习 数据类型

数据类型存在的意义&#xff1a; 给变量分配合适的内存空间&#xff0c;避免资源浪费。 整型&#xff1a; 整型变量表示的是整数类型的数据 long类型 在 windows 中4字节 linux 中 32位4字节 64位8字节&#xff0c;占用空间的不同&#xff0c;可以表示的取值范围就越广&…

python:基础知识—流程控制—函数与模块—数据结构—类与GUI和Turtle—异常处理与文件,概括全书(上万字最详细版)

这里是一张夜景&#xff0c;给大家放松一下。 !&#xff01;无锡南长街 文章目录 模块一&#xff1a;基础知识1、python语言2、常见数字类型3、字符串4、数字类型转换5、标识符命名6、常见关键字7、运算符与表达式&#xff08;1&#xff09;算术运算符&#xff08;2&#xff09…

ZooKeeper的集群部署和启动与关闭

ZooKeeper是一个分布式应用程序协调服务。一个ZooKeeper集群可以存在多个Follower和Observer服务器&#xff0c;但只允许存在一台Leader服务器。如果Leader服务器宕机&#xff0c;那么ZooKeeper集群的其它服务器会投票选举出一个新的Leader服务器&#xff0c;为防止投票数不过半…

Elasticsearch:部署 ELSER - Elastic Learned Sparse EncoderR

警告&#xff1a;此功能处于技术预览阶段&#xff0c;可能会在未来的版本中更改或删除。 Elastic 将尽最大努力修复任何问题&#xff0c;但技术预览中的功能不受官方 GA 功能的支持 SLA 约束。 Elastic Learned Sparse EncodeR - 或 ELSER - 是由 Elastic 训练的检索模型&#…

浅谈中移链中插件的功能及使用

中移链是在满足我国信息化监管需求、合规可控的前提下&#xff0c;打造的中国移动区块链服务平台。它允许使用插件来扩展其功能&#xff0c;以适应各种不同的使用场景。 什么是中移链插件呢&#xff1f;如果把中移链比作一个操作系统&#xff0c;那么插件就类比于操作系统上的…

工作流引擎Flowable

这里写目录标题 1.Flowable基础1.1 入门学习 2.流程图设计器2.1 FlowableUI2.1.1 绘制流程图 1.Flowable基础 官方手册 1.1 入门学习 一、依赖 <dependencies><dependency><groupId>org.flowable</groupId><artifactId>flowable-engine</…