一、ØMQ模式概述
- 在ØMQ的套接字API下是消息传递模式的世界
-
让我们概括一下ØMQ所做的工作:
- 它快速而高效地把整块数据(消息)发送到节点,这里的节点可以是线程、进程或节点
- ØMQ给你的应用程序提供一个单独套接字API来开展工作,而不管实际使用的传输协议是什么(例如,进程内、进程间、TCP或多播等)
- 各对等点撤销或接入的时候,ØMQ套接字都会自动重新连接
- 它会根据需要消息同时在发送者和接收者处进行排队。它仔细地管理这些队列,以确保进程不会耗尽内存而在适当的时候溢出到磁盘
- 它会处理套接字错误,在后台执行所有的I/O,并采用无锁技术在节点之间进行会话,所以永远不会有锁定、等待、信号量或死锁问题
- 总结上面的这一切,ØMQ根据模式(pattern)来完成这一切
- ØMQ的模式是硬编码的,但未来的版本可能允许用户自定义模式
二、ØMQ的模式分类
- ØMQ模式在zmq_socket()接口中有介绍,可以参阅:http://api.zeromq.org/master:zmq-socket
①客户端-服务器模式(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_PUB、ZMQ_SUB、ZMQ_XPUB、ZMQ_XSUB
- 详情参阅:https://blog.csdn.net/qq_41453285/article/details/106877202
④请求-回复模式
- 套接字类型可以设置为:ZMQ_REQ、ZMQ_REP、ZMQ_DEALER、ZMQ_ROUTER
- 详情参阅:
⑤流水线模式
- 套接字类型可以设置为:ZMQ_PUSH、ZMQ_PULL
- 详情参阅:
⑥独占对模式
- 套接字类型可以设置为:ZMQ_PAIR
- 详情参阅:
⑦本机模式
- 套接字类型可以设置为:ZMQ_STREAM
- 详情参阅:
三、模式的匹配
- 对于不同的套接字需要匹配特定的模式才可以正常的进行工作,否则将产生错误
- 当然,你也可以通过代码来桥接其他套接字类型(例如,从一个套接字类型读取并写入另一个套接字类型)
四、高级别消息传递模式
- 上面介绍的模式都是ZeroMQ自带的模式,在这些基础上,我们可以自己设计各种高级别的模式
- 例如,我们在后面文章会介绍“异步管家”模式、“双星”模式等