重头戏!带你全览ZeroMQ的七大消息模式

一、ØMQ模式概述

  • 在ØMQ的套接字API下是消息传递模式的世界
  • 让我们概括一下ØMQ所做的工作:
    • 它快速而高效地把整块数据(消息)发送到节点,这里的节点可以是线程、进程或节点
    • ØMQ给你的应用程序提供一个单独套接字API来开展工作,而不管实际使用的传输协议是什么(例如,进程内、进程间、TCP或多播等)
    • 各对等点撤销或接入的时候,ØMQ套接字都会自动重新连接
    • 它会根据需要消息同时在发送者和接收者处进行排队。它仔细地管理这些队列,以确保进程不会耗尽内存而在适当的时候溢出到磁盘
    • 它会处理套接字错误,在后台执行所有的I/O,并采用无锁技术在节点之间进行会话,所以永远不会有锁定、等待、信号量或死锁问题
  • 总结上面的这一切,ØMQ根据模式(pattern)来完成这一切
  • ØMQ的模式是硬编码的,但未来的版本可能允许用户自定义模式

二、ØMQ的模式分类

①客户端-服务器模式(Client-server)

  • 客户机-服务器模式用于允许一个ZMQ_SERVER服务器与一个或多个ZMQ_CLIENT客户机通信。客户端总是启动对话,之后任何一方都可以向另一方异步发送消息
  • 客户机-服务器模式由http://rfc.zeromq.org/spec:41正式定义
  • 该模式仍在草案阶段

ZMQ_CLIENT

  • ZMQ_CLIENT套接字与ZMQ_SERVER套接字通信。任何一个对等点都可以连接,但是通常推荐的模型是绑定ZMQ_SERVER并连接ZMQ_CLIENT
  • 如果ZMQ_CLIENT套接字已经建立了连接,zmq_send()将接受消息,将它们排成队列,并在网络允许的情况下尽可能快地发送它们。传出缓冲区限制由套接字的高水位标志定义。如果传出缓冲区已满,或者没有连接的对等点,zmq_send()将默认阻塞。ZMQ_CLIENT套接字不会删除消息
  • 当ZMQ_CLIENT套接字连接到多个ZMQ_SERVER套接字时,发送出去的消息将在连接的对等端之间循环分发。同样,ZMQ_CLIENT套接字公平地从每个连接的对等端接收消息。这种用法仅适用于无状态协议
  • ZMQ_CLIENT套接字是线程安全的,可以从多个线程同时使用。注意,来自ZMQ_SERVER套接字的响应将发送到调用zmq_msg_recv()的第一个客户机线程。如果需要获得对原始线程的响应,每个线程使用一个ZMQ_CLIENT套接字
  • ZMQ_CLIENT套接字是线程安全的。它们在发送时不接受ZMQ_SNDMORE选项,而在接收时不接受ZMQ_RCVMORE。这就限制了他们只能使用单个部件的数据。其目的是扩展API以允许分散/收集多部分数据
                                                   ZMQ_CLIENT特性摘要 
兼容的对等套接字ZMQ_SERVER
方向双向的
发送/接收模式无限制
外发路由策略扇出(Fan out)
入网路由策略公平排队
静音状态下的操作阻塞

ZMQ_SERVER

  • ZMQ_SERVER套接字与一组ZMQ_CLIENT套接字通信。ZMQ_SERVER套接字只能应答传入消息:ZMQ_CLIENT对等端必须始终发起对话
  • 每个接收到的消息都有一个routing_id,它是一个32位无符号整数。应用程序可以使用zmq_msg_routing_id(3)来获取它。要向给定的ZMQ_CLIENT对等点发送消息,应用程序必须使用zmq_msg_set_routing_id(3)在消息上设置对等点的routing_id
  • 如果没有指定routing_id,或者没有引用已连接的客户端对等点,则发送调用将在EHOSTUNREACH中失败。如果客户端对等端的传出缓冲区已满,发送调用将阻塞,除非在发送中使用ZMQ_DONT_WAIT,在这种情况下,它将通过EAGAIN失败。ZMQ_SERVER套接字在任何情况下都不应该丢失消息
  • ZMQ_SERVER套接字是线程安全的。它们在发送时不接受ZMQ_SNDMORE选项,而在接收时不接受ZMQ_RCVMORE。这就限制了他们只能使用单个部件的数据。其目的是扩展API以允许分散/收集多部分数据
                                                   ZMQ_SERVER特性摘要 
兼容的对等套接字ZMQ_CLIENT
方向双向的
发送/接收模式无限制
外发路由策略扇出(Fan out)
入网路由策略公平排队
静音状态下的操作返回EAGAIN

②广播盘模式(Radio-dish)

  • 广播盘模式用于以扇出方式将数据从单个发布者一对多分发到多个订户。
  • Radio-dish正在使用组(相对于Pub-sub主题),Dish套接字可以加入一个组,Radio套接字发送的每个消息都属于一个组。
  • 组是限制为16个字符长度(包括null)的以null终止的字符串。目的是将长度增加到40个字符(包括null)。组的编码应为UTF8。
  • 使用完全匹配(vs PubSub的前缀匹配)来匹配组
  • 广播碟仍处于草案阶段

ZMQ_RADIO

  • 发布者使用ZMQ_RADIO类型的套接字来分发数据。每个消息都属于一个组,使用zmq_msg_set_group()指定一个组。邮件将分发给组中的所有成员。所述zmq_recv()函数不是此套接字类型实现。
  • 当ZMQ_RADIO套接字由于已达到订户的最高水位而进入静音状态时,将发送给有问题的订户的任何消息都将被丢弃,直到静音状态结束为止。对于该套接字类型,zmq_send()函数将永远不会阻塞。
  • ZMQ_RADIO套接字是线程安全的。他们在发送时不接受ZMQ_SNDMORE选项。这将它们限制为单个零件数据
                                                                                                   ZMQ_RADIO特性摘要 
兼容的对等套接字ZMQ_DISH
方向单向
发送/接收模式仅发送
入网路由策略不适用(N/A)

外发路由策略

扇出(Fan out)
静音状态下的操作下降(Drop)

ZMQ_DISH

  • 用户使用ZMQ_DISH类型的套接字来订阅由无线电分发的组。最初,ZMQ_DISH套接字未订阅任何组,请使用zmq_join()加入一个组。要获取该组,消息属于zmq_msg_group()。该zmq_send()函数没有此套接字类型实现。
  • ZMQ_DISH套接字是线程安全的。他们不接受ZMQ_RCVMORE。这将它们限制为单个零件数据。
                                                   ZMQ_DISH特性摘要 
兼容的对等套接字ZMQ_RADIO
方向单向
发送/接收模式仅接收
入网路由策略公平排队
外发路由策略不适用(N/A)

③发布订阅模式

④请求-回复模式

⑤流水线模式

⑥独占对模式

⑦本机模式

  • 套接字类型可以设置为:ZMQ_STREAM
  • 详情参阅:待续。

三、模式的匹配

  • 对于不同的套接字需要匹配特定的模式才可以正常的进行工作,否则将产生错误
  • 当然,你也可以通过代码来桥接其他套接字类型(例如,从一个套接字类型读取并写入另一个套接字类型)

四、高级别消息传递模式

  • 上面介绍的模式都是ZeroMQ自带的模式,在这些基础上,我们可以自己设计各种高级别的模式
  • 例如,我们在后面文章会介绍“异步管家”模式、“双星”模式等。

  • 我是小董,V公众点击"笔记白嫖"解锁更多【ZeroMQ】资料内容。

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
ZeroMQ 的发布订阅模式(Publish-Subscribe)是一种常用的消息传递模式,适用于需要发布和订阅消息的场景,例如多人聊天室、订阅新闻、实时数据传输等。 在发布订阅模式中,消息发布者(Publisher)将消息发送到一个或多个主题(Topic),消息订阅者(Subscriber)可以根据自己的需求订阅感兴趣的主题,从而接收到相应的消息。发布订阅模式支持一对多和多对多的消息传递,可以实现广播、多播等功能。 具体实现时,可以使用 ZeroMQ 的 PUB-SUB 套接字组合来实现发布订阅模式消息发布者使用 PUB 套接字将消息发送到指定的主题,消息订阅者使用 SUB 套接字订阅感兴趣的主题,并接收相应的消息。需要注意的是,订阅者必须在发布者发送消息之前订阅相应的主题,否则无法接收到消息。 以下是使用 ZeroMQ 实现发布订阅模式的示例代码: Publisher: ```python import zmq context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5555") while True: topic = input("Enter topic: ") message = input("Enter message: ") socket.send_string(f"{topic} {message}") ``` Subscriber: ```python import zmq context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5555") topic_filter = input("Enter topic filter: ") socket.setsockopt_string(zmq.SUBSCRIBE, topic_filter) while True: message = socket.recv_string() topic, content = message.split(' ', 1) print(f"[{topic}] {content}") ``` 在这个示例中,消息发布者通过 PUB 套接字将消息发送到指定的主题,消息订阅者通过 SUB 套接字订阅感兴趣的主题,并接收相应的消息。需要注意的是,订阅者必须在发布者发送消息之前订阅相应的主题,否则无法接收到消息

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值