RabbitMQ高阶使用消息推送

news2024/9/26 1:28:45

目录

  • 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;
    }
}

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

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

相关文章

学生党暑假在家赚钱得方法,足不出户轻松赚取买鞋钱

很多学生党都想在暑假期间赚点零花钱&#xff0c;最好是能在家就赚钱。在家里赚零花钱有许多途径&#xff0c;今天我来和大家分享一些方法。 1、问答在各大平台上非常普遍。 我们可以在各大平台上找到各种各样的问答。 如今&#xff0c;问答平台越来越多&#xff0c;提供的奖…

平凯星辰重磅支持 2023 开放原子全球开源峰会,开源数据库分论坛成功召开

2023 年 6 月 11 日至 13 日&#xff0c;以“开源赋能&#xff0c;普惠未来”为主题的 2023 开放原子全球开源峰会开幕式暨高峰论坛在北京成功举办。企业级开源分布式数据库厂商平凯星辰联合创始人兼 CTO 黄东旭受邀出席峰会参与开源论道圆桌&#xff0c;担任开源数据库分论坛出…

吴恩达ChatGPT课爆火

点上方计算机视觉联盟获取更多干货 没想到时至今日&#xff0c;ChatGPT竟还会犯低级错误&#xff1f; 吴恩达大神最新开课就指出来了&#xff1a; ChatGPT不会反转单词&#xff01; 比如让它反转下lollipop这个词&#xff0c;输出是pilollol&#xff0c;完全混乱。 哦豁&#…

C++14中返回类型推导的使用

使用C14中的auto返回类型&#xff0c;编译器将尝试自动推导(deduce)返回类型: namespace {int xx 1; auto f() { return xx; } // return type is int const auto& f3() { return xx; } // return type is const int&auto multiply(int a, int b) { return (a * b); …

【阅读论文】时间序列数据清洗:一项调查

文章目录 摘要一、引言A.问题陈述B.问题挑战C. 组织 二、基于平滑的清洗算法A.移动平均B.自动注册C.卡尔曼滤波模型D.总结和讨论 三、基于约束的混合算法A. 顺序依赖 (OD)B.序列相关性C.速度约束D.总结和讨论 四、基于统计的CLEANING算法A.最大似然B.马尔可夫模型C.二项抽样D.时…

基于51单片机设计的井下瓦斯监控系统

一、项目介绍 井下瓦斯监控系统是煤矿安全生产中非常重要的一部分,防止井下瓦斯爆炸事故的发生,保障煤矿工人的人身安全。由于地下环境特殊,需要特殊的监测系统来实时监测瓦斯浓度等关键指标,并及时报警以便采取措施进行处理。 瓦斯气体,又称沼气,是一种轻质烃类气体,…

基于的滤波器设计

一,带通滤波器设计指标。 1&#xff0c;中心频率。中心频率:通常定义为带通滤波器&#xff08;或带阻滤波器&#xff09;频率的几何平均值&#xff0c;在对数坐标下&#xff0c;即为两个3dB点之间的中点&#xff0c;一般用两个3dB点的算术平均来表示。滤波器通频带中间的频率&…

网工大题题型总结(1)-------网络安全方面考察

&#xff08;1&#xff09;2018年上半年 试题二 &#xff08;3&#xff09;常见的无线网络安全隐患有 IP 地址欺骗、数据泄露、(8)、(9)、双络通信被窃听等; 为保护核心业务数据区域的安全&#xff0c;网络管理员在设备①处部署(10)实现核心业务区域边界 防护;在设备②处部署…

C++11特性之左值引用和右值引用

3.1二者的对比之内置类型 内置类型的无名对象&#xff08;右值&#xff09;为纯右值&#xff0c;其值本身不可改变 int main() {int a10;const int b20;int& raa;//ok,左值引用const int& rbb;//ok&#xff0c;常性左值引用const int& crv30;//ok,也叫万能引用&a…

网络安全竞赛——综合靶机渗透测试ZHCS-2全过程解析教程

任务一:综合靶机渗透测试 任务环境说明: 服务器场景:ZHCS-2(关闭连接)服务器场景操作系统:版本不详扫描目标靶机将靶机开放的所有端口,当作flag提交(例:21,22,23) FLAG:22,80 扫描目标靶机将靶机的http服务版本信息当作flag提交(例:apache 2.3.4) FLAG: ligh…

Vue3 Hooks函数使用及封装思想

目录 一. 什么是hooks函数&#xff1f; 二、如何封装一个hooks函数 三、Hooks 常用 Demo &#xff08;1&#xff09;验证码倒计时 &#xff08;2&#xff09;防抖 &#xff08;3&#xff09;节流 一. 什么是hooks函数&#xff1f; 专业解释&#xff1a;Vue 3中的Hooks函数…

Nucleo-F411RE (STM32F411)LL库体验 8 - PWM的使用

Nucleo-F411RE &#xff08;STM32F411&#xff09;LL库体验 8 - PWM的使用 1、简述 LD2连接PA5&#xff0c;而PA5可以映射TIM2_CH1&#xff0c;配合TIM2&#xff0c;可以输出PWM。 本片文章大量工作是添加了shell命令&#xff0c;可以通过pwm命令开关pwm以及设置pwm的频率&am…

数字图像处理期末考点整理(全)

计算&#xff1a;傅里叶变换&#xff0c;双线性插值&#xff0c;直方图均衡化&#xff0c;灰度共生矩阵&#xff0c;霍夫曼编码&#xff0c;区域增长/合并&#xff0c;中值滤波 简答&#xff1a;窗口/模板处理&#xff0c;BMP文件存储格式&#xff0c;滤波器和平滑算子的特点&…

Servlet (上篇)

哥几个来学 Servlet 啦 ~~ 目录 &#x1f332;一、什么是 Servlet &#x1f333;二、第一个 Servlet 程序 &#x1f347;1. 创建项目 &#x1f348;2. 引入依赖 &#x1f349;3. 创建目录 &#x1f34a;4. 编写代码 &#x1f34b;5. 打包程序 &#x1f96d;6. 部署程序…

client-go的Indexer三部曲之二:性能测试

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 本文是《client-go的Indexer》系列的第二篇&#xff0c;在前文咱们通过实例掌握了client-go的Indexer的基本功能&#xff0c;本篇咱们尝试对下面这…

css小兔鲜项目搭建

目录 精灵图 精灵图的使用步骤 背景图片大小 background连写 文字阴影 盒子阴影 过渡 骨架标签 SEO三大标签 版心的介绍 css书写顺序 项目结构搭建 精灵图 场景&#xff1a;项目中将多张小图片&#xff0c;合并成一张大图片&#xff0c;这张大图片称之为精灵图 优点…

c语言实现 顺序存储和链式存储(几种链表)

目录 一、简介 二、一些问题 1、递归free 2、free单向循环链表&#xff1a; 3、free单向链表 4、free双向循环链表 5、free使用数组实现链式存储结构 6、sizeof&#xff08;&#xff09;求字符串大小的问题 三、总结 一、简介 花了几天的时间从头开始使用c语言…

UnityVR--UIManager--UI管理2

目录 前言 UIManger的实现 1. 需要用到的变量和数据 2. 在构造中的工作 3. 初始化面板 4. 显示面板 5. 隐藏面板和隐藏所有面板 6. 其他小工具 在场景中实现 1. 不同面板的类型设置 2. 场景中的设置 前言 接前篇&#xff0c;上一篇已经有了UITools.cs其中定义了UI面板需…

Web服务器群集:部署LAMP平台

目录 一、理论 1.LAMP平台 2.Apache网址服务基础 2.httpd服务器的基本配置 3.构建虚拟Web主机 4.MySQL服务 5.构建PHP运行环境 二、实验 1.LAMP架构DISCUZ论坛应用 三、问题 1.虚拟机内存分配上限问题&#xff0c;内存上限只能加到3G。 2.虚拟机CPU如何设置才更加合…

RISC-V 函数调用约定和Stack使用

RISC-V 函数调用约定和Stack使用 引言RISC-V vs x86RISC-V寄存器StackStruct补充函数调用约定寄存器约定函数跳转和返回指令的编程约定被调用函数的编程约定 RISC-V 汇编与 C 混合编程RISC-V 汇编调用 C 函数C 函数中嵌入 RISC-V 汇编 引言 MIT 6.S081 2020 操作系统 本文为M…