Apache BifroMQ 3.3.5 安装指南
Apache BifroMQ 3.3.5 安装指南:Ubuntu 22.04 从零安装单机版,涵盖 JDK 17 前置、官方包 sha256 校验、启停、MQTT 收发与 REST 验证、systemd 托管及 JVM 堆调优,均实测
Apache BifroMQ 3.3.5 安装指南
目标:在 Ubuntu 22.04 服务器上从零安装 Apache BifroMQ 3.3.5 单机版(standalone),覆盖 OpenJDK 17 前置、官方发行包下载与 sha256 校验、目录部署、服务启停、MQTT 连通与基础收发验证(QoS0/QoS1/保留消息)、REST API 验证、systemd 托管及 JVM 堆 256-512MB 调优。以下命令与回显均在 Ubuntu 22.04.5 真实环境逐步实测。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Java:OpenJDK 17.0.20.1(
openjdk-17-jdk-headless,BifroMQ 硬性要求 JDK 17+) - Apache BifroMQ:3.3.5(官方
standalone二进制发行包,126,286,685 字节 ≈ 120MB) - 安装目录:
/usr/share/bifromq - 数据目录:
/usr/share/bifromq/data(启动时自动创建,RocksDB 引擎) - 日志目录:
/usr/share/bifromq/logs(启动时自动创建) - 服务端口:MQTT TCP 1883、MQTT over WebSocket 8080、HTTP 管理 API 8091、Prometheus 指标 9090
- 客户端工具:mosquitto-clients 2.0.11(
mosquitto_pub/mosquitto_sub) - 运行用户:root
💡 说明:BifroMQ 是 Apache 顶级候选的分布式 MQTT 消息中间件(源自百度,2024 年进入 Apache 孵化器,现已毕业),单机版开箱即用:内置 basekv 分布式存储(RocksDB 引擎)承载会话、订阅与保留消息,无需任何外部数据库或注册中心。
二、前置条件
- 一台 Ubuntu 22.04 服务器,root 权限。
- 磁盘:安装包约 120MB,解压后约 300MB,另为数据目录预留 2GB 以上。
- ⚠️ /tmp 必须可执行:BifroMQ 启动时会把 netty 原生库(libnetty_transport_native_epoll)解压到
/tmp并加载执行,若/tmp挂载了noexec选项,MQTT 订阅会异常(SUBACK 返回 128),详见「常见问题」。 - 工具包:
wget、curl、net-tools(含netstat)、procps(含jps)、mosquitto-clients。
三、版本选型说明
Apache BifroMQ 的发布渠道随大版本变化,截至本文实测(2026-10):
| 版本线 | 最新版本 | 二进制获取渠道 | 说明 |
|---|---|---|---|
| 4.x | 4.0.0-incubating(2026-01-28) | downloads.apache.org | 4.x 与 3.x 不兼容,二进制不在 GitHub Releases 挂资产 |
| 3.x | 3.3.5(2025-02-25) | GitHub Releases | 本文采用;GitHub 资产可直接 wget |
通过 GitHub API 核实(节选):
v4.0.0-incubating | prerelease: False | 2026-01-28 (无 GitHub 二进制资产)
v3.3.5 | prerelease: False | 2025-02-25
asset: bifromq-3.3.5-standalone.tar.gz 126286685
asset: bifromq-3.3.5-windows-standalone.zip 126328405
⚠️ 仓库迁移坑:项目原地址
bifromq/bifromq已迁移为apache/bifromq,老链接https://github.com/bifromq/bifromq/releases/download/...会 404,请使用新地址。
3.3.5 提供两个二进制资产:
| 制品 | 说明 |
|---|---|
bifromq-3.3.5-standalone.tar.gz | Linux 单机版发行包(本文采用) |
bifromq-3.3.5-windows-standalone.zip | Windows 单机版 |
四、安装步骤
4.1 安装 JDK 17 与基础工具
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y \
openjdk-17-jdk-headless wget curl net-tools procps mosquitto-clients
验证版本回显:
java -version
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
确认 JAVA_HOME 实际路径(后续 systemd 配置要用):
readlink -f $(which java)
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
即 JAVA_HOME 为 /usr/lib/jvm/java-17-openjdk-amd64。
💡 启动脚本对 Java 版本做硬校验:低于 17 直接退出并提示
Too old Java version xxx, at least Java 17 is required。
4.2 下载发行包并校验 sha256
cd /opt
wget --tries=3 --timeout=60 -O bifromq-3.3.5-standalone.tar.gz \
https://github.com/apache/bifromq/releases/download/v3.3.5/bifromq-3.3.5-standalone.tar.gz
下载完成校验:
sha256sum /opt/bifromq-3.3.5-standalone.tar.gz
dd739c43b441dd5008f81543911bea5ec3b3662fdb52d3a9fbd187e902ca76b9 /opt/bifromq-3.3.5-standalone.tar.gz
4.3 解压部署
mkdir -p /usr/share/bifromq
tar -zxf /opt/bifromq-3.3.5-standalone.tar.gz --strip-components 1 -C /usr/share/bifromq/
ls /usr/share/bifromq/
bin
conf
lib
plugins
ls /usr/share/bifromq/bin /usr/share/bifromq/conf
/usr/share/bifromq/bin:
bifromq-start.sh
bifromq-stop.sh
standalone.sh
/usr/share/bifromq/conf:
logback.xml
standalone.yml
| 目录/文件 | 说明 |
|---|---|
bin/standalone.sh | 单机版主控脚本,用法 {start|stop|restart} [-fg] |
bin/bifromq-start.sh | 实际拉起 JVM 的脚本(堆推导、GC 参数、nohup) |
bin/bifromq-stop.sh | 按 StandaloneStarter 进程名找 PID 并停止 |
conf/standalone.yml | 主配置文件(YAML,覆盖默认值) |
conf/logback.xml | 日志配置 |
lib/ | 全部依赖 jar |
plugins/ | 插件目录,自带 demo-plugin-3.3.5.jar(含 Prometheus 9090 导出器、事件日志、演示鉴权提供器) |
data/、logs/ | 首次启动自动创建 |
4.4 首次启动
cd /usr/share/bifromq
./bin/standalone.sh start
回显:
Using Java Version 17.0.20.1 locating at 'java'
Total Memory: 31 GB
com.baidu.bifromq.starter.StandaloneStarter process started: 4256
💡 堆推导规则(
bifromq-start.sh实读):默认取总内存的 70% 作为-Xmx,再取其一半作为-Xms;MaxDirectMemorySize取总内存 20%;GC 默认 ZGC。31GB 内存的机器实测默认参数为-Xms11217m -Xmx22435m。可用JVM_HEAP_OPTS或MEM_LIMIT环境变量覆盖(见 4.7 节)。
检查端口监听:
netstat -lntp | grep -E "1883|8080|8091|9090"
tcp6 0 0 :::9090 :::* LISTEN 4256/java
tcp6 0 0 172.17.0.3:8091 :::* LISTEN 4256/java
tcp6 0 0 :::8080 :::* LISTEN 4256/java
tcp6 0 0 :::1883 :::* LISTEN 4256/java
| 端口 | 用途 | 默认状态 |
|---|---|---|
| 1883 | MQTT over TCP | 开启 |
| 8080 | MQTT over WebSocket(路径 /mqtt) | 开启 |
| 8091 | HTTP 管理 API(REST) | 开启;默认绑定在 site-local 地址上(本例 172.17.0.3),用 127.0.0.1:8091 访问不通,需用本机实际网卡地址 |
| 9090 | Prometheus 指标(DemoPlugin 提供) | 开启 |
| 1884 / 8443 | MQTT over TLS / WSS | 默认关闭 |
| 8090 | HTTPS 管理 API | 默认关闭 |
⚠️ 首次启动约需 30~60 秒完成内部存储(inbox store / retain store / dist worker)引导,期间端口可能尚未全部就绪,属正常现象。
4.5 MQTT 连通与基础收发验证
安装 mosquitto 客户端后做完整闭环(先开订阅,再发布):
# 终端 1:后台订阅 native/# 通配主题
(timeout 12 mosquitto_sub -h 127.0.0.1 -p 1883 -t "native/#" -v > /tmp/native.txt 2>&1 &)
# 终端 2:分别以 QoS1、QoS0 发布,并以 QoS1 发一条保留消息
mosquitto_pub -h 127.0.0.1 -p 1883 -t native/q1 -m "native-qos1-ok" -q 1
mosquitto_pub -h 127.0.0.1 -p 1883 -t native/q0 -m "native-qos0-ok" -q 0
mosquitto_pub -h 127.0.0.1 -p 1883 -t native/ret -m "native-retained" -q 1 -r
# 回看订阅端
cat /tmp/native.txt
订阅端实际收到(三条全部通过):
native/q1 native-qos1-ok
native/q0 native-qos0-ok
native/ret native-retained
保留消息语义验证(新建订阅者应立即收到该主题最后一条保留消息):
mosquitto_sub -h 127.0.0.1 -p 1883 -t "native/ret" -C 1 -W 4
native-retained
QoS1 发布确认(-d 调试模式):
mosquitto_pub -h 127.0.0.1 -p 1883 -t native/q1 -m "ack-test" -q 1 -d
Client (null) sending CONNECT
Client (null) received CONNACK (0)
Client (null) sending PUBLISH (d0, q1, r0, m1, 'native/q1', ... (8 bytes))
Client (null) received PUBACK (Mid: 1, RC:0)
Client (null) sending DISCONNECT
4.6 REST API 验证
BifroMQ 内置 HTTP 管理 API(默认 8091,绑定本机 site-local 地址)。注意:3.3.x 的接口参数通过 HTTP Header 传递,不是 JSON body,报文体即消息 payload:
curl -X POST http://172.17.0.3:8091/pub \
-H "req_id: 710000031" -H "tenant_id: bifromq" -H "topic: rest/verify" \
-H "qos: 0" -H "client_type: curl" -H "client_meta_lang: zh" \
--data-binary "rest-pub-works"
回显:
NO_MATCH
NO_MATCH 且 HTTP 200 表示发布成功、当前无匹配订阅者,属正常返回。会话查询接口(不依赖 dist 子系统,适合做存活探测):
curl -s -o /dev/null -w "%{http_code}\n" -X GET "http://172.17.0.3:8091/session" \
-H "tenant_id: bifromq" -H "user_id: u1" -H "client_id: not-exist"
404
对不存在的会话返回 404 即为正常。全部接口:POST /pub、POST /retain、GET/DELETE /session、DELETE /kill、PUT /sub、DELETE /unsub。
4.7 JVM 堆调至 256-512MB 并用 jps 实测
cd /usr/share/bifromq
./bin/standalone.sh stop
JVM_HEAP_OPTS="-Xms256m -Xmx512m" ./bin/standalone.sh start
用 jps -v 实测进程参数:
jps -v | grep StandaloneStarter | grep -oE "\-Xms[0-9]+m \-Xmx[0-9]+m"
-Xms256m -Xmx512m
小堆下四端口(1883/8080/8091/9090)全部正常监听,MQTT 收发与 REST 接口复测通过。
另一种方式:设置 MEM_LIMIT(字节),脚本按「70% 上限、一半下限」自动推导。例如 MEM_LIMIT=536870912(512MB)时实测推导出 -Xms179m -Xmx358m。
4.8 配置 systemd 开机自启
创建 /etc/systemd/system/bifromq.service:
[Unit]
Description=Apache BifroMQ Standalone MQTT Broker
After=network.target
[Service]
Type=forking
User=root
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment="JVM_HEAP_OPTS=-Xms256m -Xmx512m"
ExecStart=/usr/share/bifromq/bin/standalone.sh start
ExecStop=/usr/share/bifromq/bin/standalone.sh stop
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now bifromq
systemctl is-active bifromq
jps -v | grep StandaloneStarter | grep -oE "\-Xms256m \-Xmx512m"
active
-Xms256m -Xmx512m
⚠️ 实测坑:
Environment=JVM_HEAP_OPTS=-Xms256m -Xmx512m(不加引号)会被 systemd 按空格拆成两个变量,jps -v里只剩-Xms256m(-Xmx丢失回落 JVM 默认值 1/4 物理内存)。值里有空格必须用双引号包住整段。
五、日志文件布局
/usr/share/bifromq/logs/
├── stdout.log # nohup 输出(启动早期日志)
├── info.log # 主日志:启动序列、Setting 全量 dump、整合配置 dump
├── warn.log / error.log
├── debug.log / trace.log
├── event.log # 事件采集(demo 插件)
├── plugin.log # 插件管理器
├── gc-<date>.log # ZGC 日志(filecount=5, 50m each)
└── basekv/ # 内置存储各组件的 balancer/data/wal 日志
启动成功标志(info.log):
Inbox store started
Retain store started
Dist worker started
MQTT broker started
API server started
Loaded plugin: bifromq-demo-plugin@3.3.5
六、常见问题
6.1 MQTT 订阅被拒(SUBACK 128 / v3.1.1 返回 0x80),发布 QoS1 偶发收不到 PUBACK
根因(本文实测踩中):/tmp 挂载了 noexec。BifroMQ 启动时把 netty 原生 epoll 库解压到 /tmp 加载执行,stdout.log 中会有如下告警:
i.n.util.internal.NativeLibraryLoader /tmp/libnetty_transport_native_epoll_x86_64...so exists but
cannot be executed even when execute permissions set; check volume for "noexec" flag
此时 CONNECT、QoS0 发布、REST 查询看起来都正常,唯独订阅路径(内部 dist 子系统)报 BatcherUnavailableException: Batcher not found(debug.log 可见),导致 SUBACK 128。
修复:让 /tmp 可执行后重启服务:
mount -o remount,exec /tmp
systemctl restart bifromq
修复后重测,订阅立即返回 0、QoS1 稳定收到 PUBACK。
6.2 访问 8091 管理接口 Connection refused
8091 默认绑定 site-local 地址(本机内网 IP)而非 127.0.0.1。先 ip addr 拿到本机地址再访问;或在 standalone.yml 的 apiServerConfig.host 显式指定 0.0.0.0 后重启。
6.3 启动报 Too old Java version
启动脚本硬校验 Java 主版本 ≥ 17。确认 JAVA_HOME 指向 JDK 17+,或 java -version 输出为 17.x。
6.4 默认堆过大/过小
默认堆 = 物理内存 × 70%,31GB 内存机器会吃 22GB。小规格服务器用 JVM_HEAP_OPTS="-Xms256m -Xmx512m" 显式指定(推荐,见 4.7 节),或用 MEM_LIMIT=536870912 让脚本按 512MB 自动推导(实测得 -Xms179m -Xmx358m)。
6.5 systemd 启动后堆参数不对
见 4.8 节:Environment= 的值含空格必须加双引号,否则空格后内容会被当成独立变量名丢弃。
6.6 连接被拒/鉴权失败
自带 demo 插件的演示鉴权提供器未配置 webhook 时会拒绝部分权限检查。生产环境应在 standalone.yml 配置 authProviderFQN 指向自己的鉴权插件,或为 demo 插件通过 -Dplugin.authprovider.url=http://<webhook>/ 提供 webhook 服务。
七、参考链接
- 官网文档(3.3.x):https://bifromq.io/docs/3.3.x/
- GitHub Releases:https://github.com/apache/bifromq/releases
- 配置手册:https://bifromq.io/docs/3.3.x/admin_guide/configuration/config_file_manual/
- HTTP API Reference:https://bifromq.io/docs/3.3.x/user_guide/api/api_reference/