ZeroMQ 4.3.5 常用 CLI 命令与工具详解
ZeroMQ(libzmq)4.3.5 常用 CLI 命令与工具详解:官方源码树 perf 基准工具 8 个(local_lat/remote_lat/local_thr/remote_thr/inproc_lat/inproc_thr/proxy_thr/benchmark_radix_tree)、curve_keygen 密钥工具、zmq-version 自编译、pyzmq 命令行用法与系统侧配套命令,每个工具含用法、参数说明与真实回显,全部逐条实测(2026-10-20)。
ZeroMQ 4.3.5 常用 CLI 命令与工具详解
目标:把 ZeroMQ(libzmq 4.3.5)相关的命令行工具一次讲全——官方源码树自带的 8 个 perf 基准工具、CURVE 密钥工具 curve_keygen、自编译版本查询小程序、pyzmq 命令行用法与系统侧配套检查命令,每个工具均给出用法、参数说明与真实运行回显。全部命令在 Ubuntu 22.04.5 LTS (x86_64) + libzmq 4.3.5 环境逐条实测,实测日期 2026-10-20。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(jammy),x86_64
- 组件版本:libzmq 4.3.5(源码编译安装至
/usr/local,2023-10-09 官方发布;pkg-config --modversion libzmq实测4.3.5) - 编译工具链:gcc 11.4.0、GNU Make 4.3
- Python 绑定:pyzmq 22.3.0(Ubuntu 22.04 仓库版 python3-zmq,动态链接系统 libzmq)
- 源码树位置:
/usr/local/src/zeromq-4.3.5(工具来源目录) - 源码包:zeromq-4.3.5.tar.gz,sha256
6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43(实测)
二、工具概览
ZeroMQ 与多数中间件不同:它没有主守护进程,因此也没有一个统一的「zeromq 命令」。日常命令行工作分布在四类工具上,本文逐一详解:
| 工具 | 来源 | 用途 |
|---|---|---|
| perf/ 基准工具 8 个 | 源码树 perf/(编译产出) | 时延/吞吐/中转/订阅树基准测量 |
| curve_keygen | 源码树 tools/(libsodium 构建时产出) | 生成 CURVE Z85 密钥对 |
| zmq-version(自编译) | 本文用 6 行 C 代码现场编译 | 打印运行时实际加载的 libzmq 版本 |
| pyzmq 命令行用法 | apt install python3-zmq | 交互式验证、最小收发自测、zmq_proxy 演示 |
| 系统侧配套命令 | 系统自带 | pkg-config / ldconfig / ldd / ss / file 检查库与端口 |
💡 说明:工具获取的前提是拿到源码树并完成编译(第三节给出 0→1 主线)。Ubuntu 仓库的 libzmq 软件包不含这些工具。
三、前置条件:编译安装 libzmq 4.3.5
工具随源码编译产出,先完成库的 0→1 安装(完整两条安装路线与排障见《Ubuntu 22.04 安装 ZeroMQ 4.3.5 指南》):
apt-get update
apt-get install -y build-essential wget pkg-config python3-zmq
cd /usr/local/src
wget https://github.com/zeromq/libzmq/releases/download/v4.3.5/zeromq-4.3.5.tar.gz
tar xf zeromq-4.3.5.tar.gz
cd zeromq-4.3.5
./configure --prefix=/usr/local
make -j$(nproc)
make install
ldconfig
实测回显(configure 关键行节选):
configure: Using 'epoll' I/O thread polling system with CLOEXEC
configure: Using built-in SHA1
configure: Using mtree implementation to manage subscriptions
configure: Building stable and legacy API (no draft API)
config.status: creating src/platform.hpp
验证安装与源码树工具目录:
pkg-config --modversion libzmq
ls -1 perf/ | grep -v -E '\.(o|cpp|d)$'
实测回显:
4.3.5
benchmark_radix_tree
inproc_lat
inproc_thr
local_lat
local_thr
proxy_thr
remote_lat
remote_thr
四、官方 perf 基准工具详解
4.1 工具形态:libtool 包装脚本与真实二进制
一个容易踩坑的细节:源码树里 perf/local_lat 等文件是 libtool 包装脚本而非 ELF 二进制(head -2 可见 #! /bin/bash),真正的可执行文件在 perf/.libs/ 下。直接对包装脚本跑 ldd 会得到误导性的 not a dynamic executable:
head -2 perf/local_lat
file perf/.libs/local_lat
ldd perf/.libs/local_lat | grep -E 'zmq|stdc'
实测回显:
#! /bin/bash
/usr/local/src/zeromq-4.3.5/perf/.libs/local_lat: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=a087f050fdb367347daa45aa7e18c45d1abd955f, for GNU/Linux 3.2.0, with debug_info, not stripped
libzmq.so.5 => /usr/local/lib/libzmq.so.5 (0x000078cde7917000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000078cde74c2000)
另一个要点:make install 不安装 perf 工具(ls /usr/local/bin/ 实测为空,仅头文件与库入库),使用时要么在源码树 perf/ 内直接跑(wrapper 自动定位 .libs),要么把 .libs/ 下的二进制拷贝到 PATH 中。
4.2 时延测量:local_lat + remote_lat 成对使用
测量 tcp 往返时延需要两个进程成对运行:local_lat 作反射端(bind),remote_lat 作主动端(connect),后者发完指定轮次后打印统计。参数顺序均为「端点 消息大小(字节) 往返次数」:
P=/usr/local/src/zeromq-4.3.5/perf
# 终端 1:反射端
$P/local_lat tcp://127.0.0.1:5555 1 10000
# 终端 2:主动端(跑完自动退出并输出统计)
$P/remote_lat tcp://127.0.0.1:5555 1 10000
remote_lat 侧实测回显:
message size: 1 [B]
roundtrip count: 10000
average latency: 53.402 [us]
解读:1 字节消息 1 万次 tcp 往返平均 53.402 微秒(回环地址、共享环境,数值供功能验证参考,非生产基准)。
4.3 吞吐测量:local_thr + remote_thr 成对使用
local_thr 作接收端统计吞吐,remote_thr 作发送端按「消息大小 消息条数」灌数据。参数顺序为「端点 消息大小(字节) 消息条数」:
P=/usr/local/src/zeromq-4.3.5/perf
# 终端 1:接收端(跑完输出统计)
$P/local_thr tcp://127.0.0.1:5558 1000 100000
# 终端 2:发送端
$P/remote_thr tcp://127.0.0.1:5558 1000 100000
local_thr 侧实测回显:
message size: 1000 [B]
message count: 100000
mean throughput: 1607251 [msg/s]
mean throughput: 12858.015 [Mb/s]
解读:1000 字节 × 10 万条,实测约 160 万条/秒(折合 12.9 Gb/s,含回环地址零网络开销因素)。
4.4 进程内基准:inproc_lat / inproc_thr 单命令运行
inproc 传输在同一进程内完成,无需成对运行,直接给「消息大小 往返次数/消息条数」两个参数:
P=/usr/local/src/zeromq-4.3.5/perf
$P/inproc_lat 100 100000
$P/inproc_thr 100 100000
实测回显:
message size: 100 [B]
roundtrip count: 100000
average latency: 16.127 [us]
message size: 100 [B]
message count: 100000
mean throughput: 3294024 [msg/s]
mean throughput: 2635.219 [Mb/s]
解读:同进程线程间往返 16.127 微秒、吞吐约 329 万条/秒,可作为同一台机器上应用内通信的性能上限参考。
4.5 中转基准:proxy_thr(4.3.5 新增)
proxy_thr 把 zmq_proxy 中转与对打流量合在一个命令里,只需「消息大小 消息条数」两个参数,用于量化 broker 中转开销。不带参数运行先看用法提示:
$P/proxy_thr
实测回显:
usage: proxy_thr <message-size> <message-count>
$P/proxy_thr 100 100000
实测回显:
message size: 100 [B]
message count: 100000
mean throughput: 6069802 [msg/s]
mean throughput: 4855.842 [Mb/s]
解读:经中转路径约 607 万条/秒——单命令即可复现,适合快速比对不同内核参数下的中转性能。
4.6 订阅树基准:benchmark_radix_tree
4.3.5 将 PUB/SUB 的订阅匹配结构升级为 radix tree(radix 树),该工具对比新旧实现(trie vs radix_tree)在海量主题下的查找耗时,无参数直接运行:
$P/benchmark_radix_tree
实测回显:
keys = 10000, queries = 1000000, key size = 20
[trie]
Average lookup time = 116.2 ns
[radix_tree]
Average lookup time = 107.0 ns
解读:1 万主题、100 万次查询的实测中,radix tree 平均查找 107.0 纳秒,快于旧 trie 的 116.2 纳秒——这正是 4.3.5 版本在订阅匹配上的改进点。
五、CURVE 密钥工具 curve_keygen
curve_keygen 用于生成 CURVE 加密所需的 Z85 编码密钥对,位于源码树 tools/,默认构建(tweetnacl)不会产出它——它依赖 libsodium。默认构建下手工编译只会得到拒绝工作的程序:
gcc tools/curve_keygen.cpp -o /usr/local/bin/curve_keygen -I include -lzmq -lstdc++
/usr/local/bin/curve_keygen
实测回显(默认构建下):
This tool generates a CurveZMQ keypair, as two printable strings you can
use in configuration files or source code. The encoding uses Z85, which
is a base-85 format that is described in 0MQ RFC 32, and which has an
implementation in the z85_codec.h source used by this tool. The keypair
always works with the secret key held by one party and the public key
distributed (securely!) to peers wishing to connect to it.
To use curve_keygen, please install libsodium and then rebuild libzmq.
正确姿势:安装 libsodium 开发包后,在全新解压目录以 --with-libsodium 重建(实测 make 会直接产出 tools/curve_keygen 二进制):
apt-get install -y libsodium-dev
cd /usr/local/src && rm -rf zmq-libsodium && mkdir zmq-libsodium && cd zmq-libsodium
tar xf ../zeromq-4.3.5.tar.gz && cd zeromq-4.3.5
./configure --prefix=/usr/local --with-libsodium
make -j$(nproc)
./tools/curve_keygen
实测回显(configure 关键行 + 密钥生成):
checking for libsodium... yes
configure: Using libsodium for CURVE security
This tool generates a CurveZMQ keypair, as two printable strings you can
use in configuration files or source code. The encoding uses Z85, which
is a base-85 format that is described in 0MQ RFC 32, and which has an
implementation in the z85_codec.h source used by this tool. The keypair
always works with the secret key held by one party and the public key
distributed (securely!) to peers wishing to connect to it.
== CURVE PUBLIC KEY ==
mQdmh1=JuKj]rb$@:jrs:Efo:L$H3g+-FE{M$n#1
== CURVE SECRET KEY ==
[>}]%6&a(#Wmh9&wEHG*(Chd[m&Ra(=]EL-m/k*D
⚠️ 注意:以上密钥对为文档演示样本,严禁用于真实环境;生产密钥必须现场生成、私钥妥善保管。每次运行输出不同密钥对。
密钥可立即投入使用——用 pyzmq 做 CURVE 加密 REQ/REP 通联实测(旧版 pyzmq 无 set_curve_* 便捷方法,用 setsockopt 底层写法):
# curve_test.py —— CURVE 加密 REQ/REP 自测
import time
import zmq
ctx = zmq.Context()
server_pub, server_sec = zmq.curve_keypair()
client_pub, client_sec = zmq.curve_keypair()
rep = ctx.socket(zmq.REP)
rep.setsockopt(zmq.CURVE_SECRETKEY, server_sec)
rep.setsockopt(zmq.CURVE_SERVER, 1)
rep.bind("tcp://127.0.0.1:5570")
req = ctx.socket(zmq.REQ)
req.setsockopt(zmq.CURVE_PUBLICKEY, client_pub)
req.setsockopt(zmq.CURVE_SECRETKEY, client_sec)
req.setsockopt(zmq.CURVE_SERVERKEY, server_pub)
req.connect("tcp://127.0.0.1:5570")
time.sleep(0.5)
req.send_string("hello-curve")
print("REQ <- REP :", rep.recv_string())
rep.send_string("ok-curve")
print("REQ <- ACK :", req.recv_string())
实测回显:
REQ <- REP : hello-curve
REQ <- ACK : ok-curve
六、自编译辅助工具 zmq-version:运行时版本一查即准
排查「链接的到底是哪个 libzmq」时,最可靠的办法是编译一个 6 行 C 程序打印运行时版本(它像真实应用一样走 pkg-config → 链接 → 动态加载全链路):
cat > zmq_version_check.c <<'EOF'
#include <zmq.h>
#include <stdio.h>
int main(void)
{
int major, minor, patch;
zmq_version(&major, &minor, &patch);
printf("libzmq %d.%d.%d\n", major, minor, patch);
return 0;
}
EOF
gcc zmq_version_check.c -o /usr/local/bin/zmq-version $(pkg-config --cflags --libs libzmq)
zmq-version
ldd /usr/local/bin/zmq-version | grep zmq
实测回显:
libzmq 4.3.5
libzmq.so.5 => /usr/local/lib/libzmq.so.5 (0x00007c7667917000)
zmq-version 与 ldd 两行交叉印证:运行时版本 4.3.5、动态库取自 /usr/local/lib。
七、pyzmq 命令行用法:免编译的验证与演示工具
装好 python3-zmq 后,python3 -c 一行即可完成大部分验证工作,是零成本的最顺手工具。
版本与绑定信息查询:
python3 -c "import zmq; print('zmq:', zmq.zmq_version(), ' pyzmq:', zmq.pyzmq_version())"
实测回显:
zmq: 4.3.5 pyzmq: 22.3.0
可用套接字类型一览:
python3 -c "import zmq; print([a for a in dir(zmq) if a in ('REQ','REP','PUB','SUB','PUSH','PULL','XPUB','XSUB','PAIR','STREAM','ROUTER','DEALER')])"
实测回显:
['DEALER', 'PAIR', 'PUB', 'PULL', 'PUSH', 'REP', 'REQ', 'ROUTER', 'STREAM', 'SUB', 'XPUB', 'XSUB']
zmq_proxy 中转演示(前端 XSUB 5560、后端 XPUB 5561,一个线程跑 proxy,主线程发布+订阅验证):
# zmq_proxy_demo.py
import time
import threading
import zmq
def proxy():
ctx = zmq.Context()
xsub = ctx.socket(zmq.XSUB)
xsub.bind("tcp://127.0.0.1:5560")
xpub = ctx.socket(zmq.XPUB)
xpub.bind("tcp://127.0.0.1:5561")
zmq.proxy(xsub, xpub)
t = threading.Thread(target=proxy, daemon=True)
t.start()
time.sleep(0.3)
ctx = zmq.Context()
pub = ctx.socket(zmq.PUB)
pub.connect("tcp://127.0.0.1:5560")
sub = ctx.socket(zmq.SUB)
sub.connect("tcp://127.0.0.1:5561")
sub.setsockopt_string(zmq.SUBSCRIBE, "")
time.sleep(0.5)
for i in range(3):
pub.send_string("news-%d" % i)
time.sleep(0.1)
got = [sub.recv_string() for _ in range(3)]
print("SUB received:", got)
实测回显:
SUB received: ['news-0', 'news-1', 'news-2']
八、系统侧配套命令
围绕 libzmq 库的日常检查,五条系统命令足够:
pkg-config:取编译参数与版本(元数据来自 /usr/local/lib/pkgconfig/libzmq.pc):
pkg-config --modversion libzmq
pkg-config --cflags --libs libzmq
实测回显:
4.3.5
-I/usr/local/include -L/usr/local/lib -lzmq
ldconfig:查动态库缓存与加载优先级(/usr/local/lib 应排在系统目录前):
ldconfig -p | grep libzmq
实测回显:
libzmq.so.5 (libc6,x86-64) => /usr/local/lib/libzmq.so.5
libzmq.so.5 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzmq.so.5
libzmq.so (libc6,x86-64) => /usr/local/lib/libzmq.so
ldd:确认某个程序实际链接的 libzmq 路径(示例见第六节,输出 /usr/local/lib/libzmq.so.5)。
ss:验证 ZeroMQ 端点监听(后台起一个 local_lat 反射端后查看):
P=/usr/local/src/zeromq-4.3.5/perf
nohup $P/local_lat tcp://127.0.0.1:5557 100 10000 > /dev/null 2>&1 &
sleep 1
ss -ltn | grep 5557
实测回显:
LISTEN 0 100 127.0.0.1:5557 0.0.0.0:*
回显中 LISTEN 行的第二列数值 100 是该监听端点的 TCP backlog——对应 ZeroMQ 的 ZMQ_BACKLOG 选项(默认值 100),监听地址 127.0.0.1:5557 与命令一致。
file:鉴别工具二进制形态(示例见 4.1 节,确认 ELF 与动态链接信息)。
九、注意事项
- 成对工具别单跑:local_lat/remote_lat、local_thr/remote_thr 必须成对使用,单跑一端会一直阻塞等待对端;脚本化测试时先起 bind 端(local_)、再起 connect 端(remote_)。
- 端点参数顺序固定:perf 工具参数顺序为「端点 消息大小 次数(或条数)」,inproc/proxy_thr 系列没有端点参数,只给「消息大小 次数」;顺序给错不会报错但数字语义全变。
- 端口复用:同一端口被前一轮测试进程占用时 bind 会失败退出(错误信息
Address already in use),换端口或先清理残留进程(ps -ef | grep local_lat)。 - 基准数字的定位:本文所有时延/吞吐数字均为共享环境的实测样例,用于验证工具链可用与量级参考,不能当作生产性能基线;生产容量规划应在目标硬件上用同一套工具重新实测。
- wrapper 与 .libs:把 perf 工具加入 PATH 时应拷贝
perf/.libs/<工具名>真实二进制而非源码树顶层的包装脚本(离开源码树后 wrapper 会失效)。 - 默认构建无 CURVE 工具:需要 curve_keygen 就必须 libsodium 构建线(第五节);两种构建产物同 soname,重建后注意
ldconfig。
十、常见问题(FAQ)
Q1:curve_keygen 运行只打印说明文字,说「please install libsodium and then rebuild libzmq」?
默认 configure 走内置 tweetnacl,CURVE 相关工具与功能受限。按第五节流程:apt-get install libsodium-dev → 全新目录 ./configure --prefix=/usr/local --with-libsodium → make → 使用源码树 tools/curve_keygen(实测可正常输出 Z85 密钥对)。
Q2:在原目录重新 configure 加了 --with-libsodium,构建产物还是 tweetnacl?
二次 configure 会复用首次的 src/platform.hpp(实测输出 config.status: src/platform.hpp is unchanged),构建决策不会刷新。先 make distclean 或换全新解压目录再 configure。
Q3:perf 工具跑 ldd 显示 not a dynamic executable,是不是静态链接?
不是。你在对 libtool 包装脚本跑 ldd(它是个 bash 脚本)。对 perf/.libs/<工具名> 跑 ldd 可看到正常的动态链接清单(4.1 节实测)。
Q4:remote_lat 报告的时延明显高于裸 TCP?
ZeroMQ 套接字自带排队、HWM、协议帧封装与 I/O 线程调度,微秒级额外开销是设计内成本;共享/虚拟化环境还会叠加调度噪声(本文实测 53.4 微秒即含此类因素)。要逼近裸金属数字需绑核、调 ZMQ_BUSY_POLL 等 DRAFT 选项。
Q5:apt 只装了 libzmq5,为什么没有这些命令? 发行版包只含运行库与开发头文件,perf/curve_keygen 等工具仅随源码构建产出,需按第三节完成源码编译。
Q6:单元测试怎么跑?
源码树 tests/ 目录内置上百个 C++ 单元测试,需构建测试目标后运行(CMake 配置 -DBUILD_TESTS=ON,或 autotools 线 make check;测试程序较多、编译耗时较长,本文未在主线展开)。
十一、参考链接
- libzmq 仓库 perf 工具源码:https://github.com/zeromq/libzmq/tree/master/perf
- curve_keygen 源码:https://github.com/zeromq/libzmq/blob/master/tools/curve_keygen.cpp
- zmq_proxy 官方文档:https://libzmq.readthedocs.io/en/latest/zmq_proxy.html
- CURVE 安全与密钥格式(Z85,RFC 32):https://libzmq.readthedocs.io/en/latest/zmq_curve.html
- pyzmq 文档:https://pyzmq.readthedocs.io/
- 本平台《ZeroMQ 4.3.5 介绍与选型指南》:《ZeroMQ 4.3.5 介绍与选型指南》
- 本平台《Ubuntu 22.04 安装 ZeroMQ 4.3.5 指南》:《Ubuntu 22.04 安装 ZeroMQ 4.3.5 指南》
- 本平台《ZeroMQ 4.3.5 部署指南》:《ZeroMQ 4.3.5 部署指南》