文章目录
- [ZeroMQ 详解:轻量级高性能消息通信框架及 C++ 使用示例](#ZeroMQ 详解:轻量级高性能消息通信框架及 C++ 使用示例)
-
- [1. 什么是 ZeroMQ?](#1. 什么是 ZeroMQ?)
- [2. ZeroMQ 的特点](#2. ZeroMQ 的特点)
-
- [2.1 高性能](#2.1 高性能)
- [2.2 无 Broker 架构](#2.2 无 Broker 架构)
- [3. ZeroMQ 通信模型](#3. ZeroMQ 通信模型)
- [3.1 Request / Reply(请求响应)](#3.1 Request / Reply(请求响应))
- [3.2 Publish / Subscribe(发布订阅)](#3.2 Publish / Subscribe(发布订阅))
- [3.3 Push / Pull(流水线)](#3.3 Push / Pull(流水线))
- [3.4 Router / Dealer](#3.4 Router / Dealer)
- [4. ZeroMQ 通信协议](#4. ZeroMQ 通信协议)
- [5. ZeroMQ 核心对象](#5. ZeroMQ 核心对象)
- [6. C++ 环境安装](#6. C++ 环境安装)
- [7. 示例一:REQ/REP 请求响应](#7. 示例一:REQ/REP 请求响应)
- [8. 示例二:PUB/SUB 实时数据发布](#8. 示例二:PUB/SUB 实时数据发布)
- [9. ZeroMQ 与 MQTT 对比](#9. ZeroMQ 与 MQTT 对比)
- [10. ZeroMQ 在无人系统中的典型架构](#10. ZeroMQ 在无人系统中的典型架构)
-
-
- [1. 实时状态广播](#1. 实时状态广播)
- [2. 控制命令](#2. 控制命令)
- [3. 数据转发](#3. 数据转发)
-
- [11. ZeroMQ 与 FastDDS 对比](#11. ZeroMQ 与 FastDDS 对比)
- [12. 总结](#12. 总结)
ZeroMQ 详解:轻量级高性能消息通信框架及 C++ 使用示例
1. 什么是 ZeroMQ?
ZeroMQ(简称 ZMQ、ØMQ)是一款高性能异步消息通信库,用于构建分布式系统中的消息传输、进程间通信(IPC)、网络通信等场景。
与传统消息队列(如 RabbitMQ、Kafka)不同,ZeroMQ 不是一个独立运行的消息服务器,而是一个嵌入式通信库。
传统消息队列架构:
Producer
|
|
Message Broker
|
|
Consumer
ZeroMQ:
Process A
|
ZeroMQ Socket
|
TCP / IPC / Inproc
|
ZeroMQ Socket
|
Process B
ZeroMQ 将网络通信、消息队列、线程模型封装在 Socket API 中,开发者无需维护连接、重连、缓存等底层逻辑。
2. ZeroMQ 的特点
2.1 高性能
ZeroMQ 采用:
- 无锁队列
- 异步 I/O
- 内存池
- 批量消息处理
- 多线程 I/O 模型
在局域网环境下可以达到百万级消息/秒。
典型性能:
| 通信方式 | 特点 |
|---|---|
| 共享内存 | 最快 |
| ZeroMQ IPC | 非常快 |
| ZeroMQ TCP | 高性能 |
| MQTT | 轻量但较慢 |
| HTTP REST | 最低 |
2.2 无 Broker 架构
ZeroMQ 不需要部署服务器。
例如:
Kafka:
Client
|
Kafka Broker
|
Client
ZeroMQ:
Client
|
ZeroMQ
|
Client
优点:
- 部署简单
- 无单点服务
- 延迟低
缺点:
- 消息持久化能力弱
- 不适合海量历史消息存储
3. ZeroMQ 通信模型
ZeroMQ 最大特点是提供多种通信模式。
3.1 Request / Reply(请求响应)
类似 RPC。
结构:
Client Server
REQ --------> REP
request
REQ <-------- REP
response
适合:
- RPC调用
- 服务查询
- 控制命令
例如:
客户端:
发送:
"get_status"
服务器:
返回:
"running"
3.2 Publish / Subscribe(发布订阅)
类似 MQTT。
结构:
Publisher
|
|
PUB socket
|
----------------
| | |
SUB SUB SUB
适合:
- 实时数据广播
- 状态监控
- 传感器数据
例如:
Radar
|
PUB
|
----------------
| |
显示端 记录端
3.3 Push / Pull(流水线)
用于任务分发。
结构:
Producer
PUSH
|
|
PULL
Worker1
Worker2
Worker3
适合:
- 多线程任务
- 计算任务分发
例如:
图片处理:
10000张图片
PUSH
Worker1
Worker2
Worker3
3.4 Router / Dealer
高级模式:
用于:
- 异步 RPC
- 服务代理
- 分布式系统
结构:
Client
DEALER
|
ROUTER
Server1
Server2
4. ZeroMQ 通信协议
ZeroMQ 支持多种传输:
| 协议 | 用途 |
|---|---|
| tcp:// | 网络通信 |
| ipc:// | Linux进程通信 |
| inproc:// | 线程通信 |
| vmci:// | VMware通信 |
示例:
TCP:
tcp://192.168.1.10:5555
IPC:
ipc:///tmp/test.sock
线程:
inproc://worker
5. ZeroMQ 核心对象
Context
上下文。
负责:
- I/O线程
- Socket管理
示例:
cpp
zmq::context_t context(1);
Socket
通信端点。
例如:
cpp
zmq::socket_t socket(
context,
zmq::socket_type::req
);
Message
消息对象:
cpp
zmq::message_t msg;
6. C++ 环境安装
Windows
推荐:
vcpkg:
bash
vcpkg install zeromq:x64-windows
安装:
libzmq
cppzmq
CMake:
cmake
find_package(cppzmq CONFIG REQUIRED)
target_link_libraries(
app
PRIVATE
cppzmq
)
7. 示例一:REQ/REP 请求响应
Server
server.cpp
cpp
#include <zmq.hpp>
#include <iostream>
int main()
{
zmq::context_t context(1);
zmq::socket_t socket(
context,
zmq::socket_type::rep
);
socket.bind(
"tcp://*:5555"
);
while(true)
{
zmq::message_t request;
socket.recv(
request,
zmq::recv_flags::none
);
std::string msg(
static_cast<char*>(request.data()),
request.size()
);
std::cout
<< "recv:"
<< msg
<< std::endl;
std::string reply="OK";
socket.send(
zmq::buffer(reply),
zmq::send_flags::none
);
}
}
Client
client.cpp
cpp
#include <zmq.hpp>
#include <iostream>
int main()
{
zmq::context_t context(1);
zmq::socket_t socket(
context,
zmq::socket_type::req
);
socket.connect(
"tcp://127.0.0.1:5555"
);
std::string request="hello";
socket.send(
zmq::buffer(request),
zmq::send_flags::none
);
zmq::message_t reply;
socket.recv(
reply,
zmq::recv_flags::none
);
std::cout
<<"reply:"
<<reply.to_string()
<<std::endl;
}
运行:
Server:
recv:hello
Client:
reply:OK
8. 示例二:PUB/SUB 实时数据发布
发布端
cpp
#include <zmq.hpp>
#include <iostream>
#include <thread>
int main()
{
zmq::context_t context(1);
zmq::socket_t pub(
context,
zmq::socket_type::pub
);
pub.bind(
"tcp://*:6000"
);
int count=0;
while(true)
{
std::string data =
"temperature "
+std::to_string(count++);
pub.send(
zmq::buffer(data),
zmq::send_flags::none
);
std::this_thread::sleep_for(
std::chrono::seconds(1)
);
}
}
订阅端
cpp
#include <zmq.hpp>
#include <iostream>
int main()
{
zmq::context_t context(1);
zmq::socket_t sub(
context,
zmq::socket_type::sub
);
sub.connect(
"tcp://127.0.0.1:6000"
);
sub.set(
zmq::sockopt::subscribe,
""
);
while(true)
{
zmq::message_t msg;
sub.recv(
msg,
zmq::recv_flags::none
);
std::cout
<<msg.to_string()
<<std::endl;
}
}
输出:
temperature 0
temperature 1
temperature 2
9. ZeroMQ 与 MQTT 对比
在工业控制、无人系统、数据采集领域,经常需要比较 ZeroMQ 和 MQTT。
| 特性 | ZeroMQ | MQTT |
|---|---|---|
| 是否需要Broker | 否 | 需要 |
| 实时性 | ★★★★★ | ★★★★ |
| 吞吐量 | ★★★★★ | ★★★ |
| 可靠存储 | 弱 | 强 |
| 公网环境 | 一般 | 优秀 |
| 设备数量 | 中小规模 | 大规模 |
| 协议复杂度 | 低 | 低 |
| 工业控制 | 优秀 | 优秀 |
10. ZeroMQ 在无人系统中的典型架构
例如:
AUV 水下机器人:
控制中心
|
ZeroMQ TCP
|
+----------------+
| 通信网关 |
+----------------+
|
-------------------------
| | |
导航模块 传感器模块 图像模块
PUB PUB PUSH
应用:
1. 实时状态广播
AUV
|
PUB
|
监控软件
数据:
json
{
"lat":39.9,
"lon":116.3,
"depth":50
}
2. 控制命令
控制端
REQ
AUV
REP
例如:
START_MISSION
STOP
RETURN_HOME
3. 数据转发
Sensor
PUSH
Worker
PULL
Storage
11. ZeroMQ 与 FastDDS 对比
结合实时通信系统:
| 项目 | ZeroMQ | FastDDS |
|---|---|---|
| 通信模型 | 消息 | 数据分发 |
| 发现机制 | 无 | 自动Discovery |
| IDL支持 | 无 | 支持 |
| QoS | 简单 | 丰富 |
| 实时性 | 高 | 更高 |
| 复杂度 | 低 | 高 |
| 跨平台 | 优秀 | 优秀 |
如果系统需要:
- 快速开发
- 多模块通信
- 数据转发
- UI实时显示
ZeroMQ 很合适。
如果系统需要:
- 自动发现
- 强QoS
- 大规模节点
- 自动数据同步
FastDDS 更适合。
12. 总结
ZeroMQ 可以理解为:
一个把 Socket、消息队列、多线程异步通信封装起来的高性能通信库。
它最大的优势:
- 无 Broker
- 高性能低延迟
- API 简洁
- 支持多种通信模型
- 非常适合 C++ 工程系统
在 Qt/C++、工业软件、机器人、无人系统、实时监控平台中,ZeroMQ 是一种非常实用的通信方案。对于中小规模实时数据交互,它通常比 HTTP、WebSocket 更高效,比完整 DDS 系统更简单。