`
m635674608
  • 浏览: 5069119 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

MQTT, XMPP, WebSockets还是AMQP?泛谈实时通信协议选型

    博客分类:
  • java
 
阅读更多

想要向服务器发送请求并获得响应?直接使用 HTTP 吧!非常简单。但是当需要通过持久的双向连接来通信时,如 WebSockets,当然你也有其它的选择。

这篇文章会简单扼要的解释 MQTT,XMPP,STOMP,AMQP,WAMP 和其它替代品。这里常被引用的 XKCD 漫画[1]之一:

 

 

等等,其实没有“实时协议”这种东西!

 

确实如此,但这里我将该术语(Realtime Protocol)当作一堆协议的代称,这类协议都是设计用于分发消息,同步数据和通过持久双向的连接来进行请求/响应。


我们先来根据它们各自的目的进行分类:

 

纯消息

 

底层协议(例如 TCP)是被设计用来将一个消息从一个发送者(sender)传递给一个接收者(receiver)。他们并不关系消息本身应该如何构建,也不关系消息的请求、获取、存储以及如何保证安全可靠。

像 WebSockets 这样在 TCP 之上的协议,添加了一些额外的功能,例如使用头部(header)传输元数据,通过多个数据包分割较大的消息,简单的身份验证,以及路由/重定向相关信息。本质上它们仍然是点对点交换数据的方式。

当涉及到构建更大,更复杂的系统时,你需要一个更高层次的通信范式:

 

发布-订阅

 

发布-订阅模式是在大规模系统中被广泛使用的通信方式,用于多对多无状态消息传递。“订阅者”(Subscribers)可以订阅“消息主题”(topics,channels,events,namespaces), “发布者”(Publishers)可以将消息发布到“消息主题”,通过路由,所有的订阅者都将收到。

这种范式是非常灵活,高效和可扩展。它将发送者与接收者隔离开,允许订阅者自由得订阅主题或取消订阅。这和我们日常订阅报纸是一样的。

有许多支持发布-订阅的协议:MQTT,STOMP,WAMP 等等。那么我们应该如何选择呢?

 

 

MQTT

 

MQTT(Message Queue Telemerty Transport)[2]是一种二进制协议,主要用于服务器和那些低功耗的物联网设备(IoT)之间的通信。

它位于 TCP 协议的上层,除了提供发布-订阅这一基本功能外,也提供一些其它特性:不同的消息投递保障(delivery guarantee),“至少一次”和“最多一次”。通过存储最后一个被确认接受的消息来实现重连后的消息恢复。


它非常轻量级,并且从设计和实现层面都适合用于不稳定的网络环境中。

 

什么时候应使用它?

 

物联网(IoT)场景中更适合,支持几乎所有语言进行开发,并且浏览器也可通过 WebSocket 来发送和接收 MQTT 消息。

同时,对于MQTT Broker,也有很多选择,如 Mosquitto[3] 或 VerneMQ[4] 以及基于云的 MQTT 平台,如 HiveMQ[5] 或 CloudMQTT[6]。

 

STOMP

 

面向流文本的消息传输协议(STOMP,Streaming Text Oriented Messaging Protocol)[7],是 WebSocket 通信标准。在通常的发布-订阅语义之上,它通过 begin/publish/commit 序列以及 acknowledgement 机制来提供消息可靠投递。

由于协议简单且易于实现,几乎所有的编程语言都有 STOMP 的客户端实现。但是在消息大小和处理速度方面并无优势。

 

什么时候会使用它?

 

当与 Apache Apollo[8] 这样的多协议代理(multi-protocol broker)中间件结合使用时,可以做许多有趣的集成。比如在浏览器的图表中不断更新 IoT 设备的数据。

 

 

选择二进制还是基于文本?

 

到目前为止,我们已经讲了两个协议:一个二进制、另一个基于文本。让我们快速比较一下差异:

通过控制线缆中光或电的打开或关闭(逻辑开关),或控制 WiFi 信号的波峰或波谷来实现计算机之间的信息交换。从原理上来说,这是基于二进制的形式。因此,从这个层面来说所有协议都是二进制协议。

信息一旦发送,接收方有两个选择:它可以将 0/1 流分组成字节序列,进而获取(解析)信息;或者可以执行额外的步骤,将其转换为文本,然后再解析此文本。

前一种方法称为(基于)二进制的。它节省了一些昂贵的操作,同时是传输任何非文本信息的标准形式。例如,图像,音频,视频或文件。当然它也可用于发送文本信息。例如,通过向每个消息增加几个字节来表达元信息,比如描述该消息的长度或类型,这样就只需将实际的消息数据转换为文本。

然而,由于在许多发布-订阅式的架构中,信息交换是基于文本的,所以许多协议选择简单地将整个信息转化为文本,从而降低复杂性并提高了可读性,当然带来的代价就是需要再消息接受后执行额外的计算任务。

 

 

WAMP

 

Web 应用消息协议(WAMP,Web Application Messaging Protocol)[9],它尝试开发一种开放的、基于文本的协议标准,并且结合了基于发布-订阅的请求/响应编程模型,同时具备强大的路由和消息投递策略。目前它被广泛用于集成 crossbar.io[10] 路由器和 autobahn 的高速缓存客户端[11]。

 

Pusher / PubNub&Co

 

那些实时通信平台即服务(Realtime platform-as-a-service)的产品,例如 Pusher 或 PubNub,通常使用它们自己的专有协议。Pusher 已经公开了它们研发的基于 JSON 协议的详细规范[12],并且鼓励第三方或社区帮助构建不同语言的客户端。Pubnub 虽然更封闭一些,但它们目前支持一系列其它开放协议进行交互,如 MQTT。

 

队列

 

有些场景下,简单的发布-订阅模式还不够。这就是队列存在的场合:它支持多种不同的消息和存储的模式。

通过获取/确认策略,消费者接收到队列的一些消息,确认他们的“消费”,处理它们,然后取下一批消息。这是一个强大同时常用的方式。

想象一下,你正在构建一个类似 Instagram 的产品,它允许用户上传图片并添加各种滤镜。应用滤镜的过程是一个计算密集型的操作。因此,不能在上传时直接进行操作,所以接收图像的服务器只是记录下在文件系统中的位置,接着将“什么图像需要使用什么样的滤镜”这个任务添加到任务队列中。

另一台专门用于处理滤镜的机器可以从任务队列中获取这个任务,读取原始图像文件,应用滤镜,并确认这个任务已经消费(完成)。之后为了水平扩展图像处理的能力,只需要添加更多的消费者(处理滤镜的机器)来处理任务队列即可。

这种模式非常易于扩展,可以添加复杂的路由策略,任务分配策略等。

AMQP

 

高级消息队列协议(AMQP,Advanced Message Queuing Protocol)[13]是各种消息队列协议中的佼佼者。RabbitMQ[14] 和 HornetQ[15] 都是实现该协议的流行中间件。

 

什么时候会使用它?

 

当简单的发布-订阅模型不能满足使用要求。AMQP 十分可靠且功能强大。当然它及它的实现并不是足够轻量级。如果你需要一个更轻量级的选择,那接下来的内容可能会更好:

 

 

 

ZeroMQ

 

ZeroMQ[16] 既是一个协议,也是一套协议实现的组件。提供比 AMQP 更高速同时去中心化的替代方案。

 

什么时候会使用它?

 

当你需要海量吞吐以及无单点故障风险的消息队列支撑你的复杂工作流,那么 ZeroMQ 是个不错的选择,当然,你需要对陡峭的学习曲线做好准备。

 

 

JMS

 

Java 消息服务(JMS,Java Messaging Service)[17],是协议同时也是 Java 消息服务规范的标准实现,同时也是 Java 企业版(JEE)规范的一部分。

 

什么时候应使用它?

 

当你使用 Java 栈,同时也为 Java Enterprise Platform 付费了,那 JMS 是最佳选择。如果没有,那就优先考虑上述那些方案。

请求/响应

 

有时我们只需要发送单个请求,并等待收到一个响应,这完全可以使用HTTP请求完成 / 。 但是既然你已经建立了一个与服务器的持久连接 ,那为什么不利用它呢?

这种通过持久连接进行的请求/响应模式的通信过程,通常被称为远程过程调用(RPC,Remote Procedure Calls)或远程方法调用(RMI,Remote Method Invocation)。AMQP 或 ZeroMQ 可以通过响应队列(response-queue)来实现这种模式,JMS 可以直接支持 Java RMI。

 

DataSync

 

DataSync 是实现实时通信的最新可选方案。

DataSync 将数据存储中的数据同步给客户端。客户端对数据的变更都将同步给所有的订阅者。DataSync 隐藏了实时通信类应用中维护数据状态的细节,降低了复杂性,并极大加快了开发速度,但它目前仍然是一种没有开放的协议标准。

 

 

目前 DataSync 已可以在几个 PaaS 平台上使用,如 deepstreamHub[18],Firebase[19] 或 Realm[20]。

 

总结一下

 

利用 deepstream[21] 的分布式实时协议(DRP,Distributed Realtime Protocol),我们有信心找到一种方法,将所有上述概念组合成一个协议,同时确保消息大小,可扩展性和互操作性方面的效率最大化。

 

参考

 

  1. https://xkcd.com/

  2. http://mqtt.org/

  3. https://mosquitto.org/

  4. https://vernemq.com/

  5. http://www.hivemq.com/

  6. https://www.cloudmqtt.com/

  7. https://stomp.github.io/

  8. https://activemq.apache.org/apollo/

  9. http://wamp-proto.org/

  10. http://crossbar.io/

  11. http://crossbar.io/autobahn/

  12. https://pusher.com/docs/pusher_protocol

  13. https://www.amqp.org/

  14. https://www.rabbitmq.com/

  15. http://hornetq.jboss.org/

  16. http://zeromq.org/

  17. http://docs.oracle.com/javaee/6/tutorial/doc/bncdq.html

  18. https://deepstreamhub.com/

  19. https://firebase.google.com/

  20. https://realm.io/

  21. https://deepstream.io/

http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=2653548793&idx=1&sn=04534ad82bbf2bafba1a0e4552f554f0&chksm=813a6161b64de877314e1ef6c09154378b224c30cb4e594cf92ec965a95680c3f762e2d75fbd&mpshare=1&scene=23&srcid=0627eMHUUjPSF7JHQAU8kjGr#rd

分享到:
评论

相关推荐

    55links友情链接网址跟踪器

    55links友情链接网址跟踪器,放在桌面,每次直接打开就可以访问55links友情链接交易平台,方便快捷。

    [AB PLC例程源码][MMS_046180]CompactFlash Data Storage.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    moore_01_0909.pdf

    moore_01_0909

    FIBR English learning

    FIBR English learning

    [AB PLC例程源码][MMS_042350]How to send-receive SMS text messages using Westermo modem.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    OIF_IEEE802.3_liaison_19OCt09.pdf

    OIF_IEEE802.3_liaison_19OCt09

    SerU,做网络安全FTP内容的实验必备

    做网络安全FTP内容的实验必备

    nagarajan_01_1107.pdf

    nagarajan_01_1107

    [AB PLC例程源码][MMS_043879]Programming in SFC and ST Language.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    mellitz_3cd_01_0318.pdf

    mellitz_3cd_01_0318

    PyQt6实战派 配套代码

    PyQt6实战派 配套代码

    陕西省省级非物质文化遗产民俗经纬度数据统计表

    陕西省省级非物质文化遗产经纬度数据统计表 统计内容包含以下字段: 1. 项目名称 2. 遗产类别 3. 入选批次 4. 所属地区 5. 申报地区/单位 6. 地理经度 7. 地理纬度 该统计表系统记录了陕西省省级非物质文化遗产的地理空间信息,为文化遗产的数字化保护与研究工作提供了重要的数据支撑。

    ran_3ck_02a_0918.pdf

    ran_3ck_02a_0918

    毕业设计-基于springboot+vue开发的汽车租赁管理系统【源码+sql+可运行】50308.zip

    毕业设计_基于springboot+vue开发的汽车租赁管理系统【源码+sql+可运行】【50308】.zip 全部代码均可运行,亲测可用,尽我所能,为你服务; 1.代码压缩包内容 代码:springboo后端代码+vue前端页面代码; 脚本:数据库SQL脚本 效果图:运行结果请看资源详情效果图 2.环境准备: - JDK1.8+ - maven3.6+ - nodejs14+ - mysql5.6+ - redis 3.技术栈 - 后台:springboot+mybatisPlus+Shiro - 前台:vue+iview+Vuex+Axios - 开发工具: idea、navicate 4.功能列表 - 系统设置:用户管理、角色管理、资源管理、系统日志 - 业务管理:汽车管理、客户管理、租赁订单 3.运行步骤: 步骤一:修改数据库连接信息(ip、port修改) 步骤二:找到启动类xxxApplication启动 4.若不会,可私信博主!!!

    Runcorder - 跑步训练管理系统

    # Runcorder - 跑步训练管理系统 Runcorder 是一款专为跑步爱好者、马拉松运动员及高校体育生设计的本地化跑步训练管理工具,基于 Python 开发,结合 Tkinter 图形界面与强大的数据处理能力,为用户提供从训练记录到数据分析的全方位支持。无论是初学者还是专业跑者,Runcorder 都能帮助你科学规划训练、精准追踪进度,并通过可视化图表直观呈现训练成果,让你的跑步训练更智能、更高效! - **多用户管理**:支持创建、加载和删除用户档案,每个用户的数据独立存储,确保隐私与安全。 - **科学训练记录**:全维度记录跑步数据,包括日期、里程、配速、自评和晨跑标记,支持智能输入校验,避免数据错误。 - **多维数据分析**:通过动态可视化图表展示跑步里程趋势、平均配速曲线,支持自定义 Y 轴范围,帮助用户深入理解训练效果。 - **高阶功能**:提供 4 种科学训练模式(有氧/无氧/混合),支持历史记录修改与删除,数据以 JSON 格式持久化存储,跨平台兼容。

    paatzsch_01_0708.pdf

    paatzsch_01_0708

    开源AI工具下载——AnythingLLMDesktop1.7.3-r2 windows版

    AnythingLLM是一个全栈应用程序,您可以使用流行的开源大语言模型,再结合向量数据库解决方案构建个人本地AI大模型知识库

    mellitz_3ck_02_0519.pdf

    mellitz_3ck_02_0519

    petrilla_01_0708.pdf

    petrilla_01_0708

    ran_3ck_01_0918.pdf

    ran_3ck_01_0918

Global site tag (gtag.js) - Google Analytics