ejabberd 常用 CLI 命令详解
按业务域逐条实测 ejabberd 26.09 的 ejabberdctl 管理命令:工具概览、节点运维、账号管理、集群、备份迁移、诊断排障五大域 40+ 条命令,全部配真实执行回显与排障实录。
ejabberd 常用 CLI 命令详解
目标:按业务域逐条实测 ejabberd 26.09 的管理命令行工具
ejabberdctl——节点运维、账号管理、集群、备份迁移、诊断排障五大域共 40+ 条命令,全部命令配真实执行回显;操作在 Ubuntu 22.04.4 LTS 部署的 ejabberd 26.09(单节点 + 双节点集群)上实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.4 LTS(x86_64);
- ejabberd:26.9.0(官方
ejabberd/ecs:26.09部署,部署过程见 《Docker Compose 部署 ejabberd 指南》,配置详解见 《ejabberd 26.09 配置参数详解》); - 命令执行形态:
docker exec ejabberd-26.09-main ejabberdctl <命令>(物理机二进制安装则直接ejabberdctl <命令>,语法完全一致); - 实测节点:单节点
ejabberd@main,另搭第二节点ejabberd@replica组成双节点集群实测集群域命令; - 实测账号:
admin、alice、bob、ops(域localhost,演示口令按 §3.7 规范); - 命令池规模:26.09 内置 34 个命令标签、300+ 条管理命令,本文覆盖日常运维最高频的 5 个域。
二、工具概览
2.1 ejabberdctl 是什么
ejabberdctl 是 ejabberd 的统一管理入口:本质是「一个临时 Erlang 客户端节点通过分布式协议 RPC 到 ejabberd 主节点执行命令」。同一命令池同时暴露为 ejabberdctl(CLI)、REST API(mod_http_api)、WebAdmin(网页)与 ad-hoc(XMPP 会话内)四种形态——学会 ejabberdctl 等于学会全部管理接口。
无参数运行 ejabberdctl 会列出基础子命令;ejabberdctl help 是元命令系统:
ejabberdctl help
实测回显(输出节选):
This special help command provides help of ejabberd commands.
The format is:
ejabberdctl help [tags | commands | tag | command | com?*]
The optional arguments:
tags Show all tags and commands names in each tag
commands Show all tags and commands details in each tag
tag Show commands related to this tag
command Show detailed description of this command
com?* Show commands that match this glob.
2.2 命令标签全景
ejabberdctl help tags 输出 26.09 的全部命令域(实测):
accounts acme announce async cluster config db documentation ejabberdctl erlang last logs mam mnesia modules muc muc_room muc_sub oauth offline private purge roster server session shared_roster_group sql stanza statistics vcard
34 个标签按运维关注度分层:accounts(账号)、cluster(集群)、config(配置)、db(数据库迁移)、mnesia(内置库诊断)、muc*(群聊)、session(在线会话)、shared_roster_group(共享名册)、statistics(统计)、vcard(名片)、acme(证书)是日常主力。
2.3 help 的三种用法(实测)
# 用法一:看某标签下全部命令
ejabberdctl help accounts
实测回显:
accounts
ban_account change_password check_account check_password
check_password_hash count_banned delete_old_users delete_old_users_vhost
get_ban_details list_banned register registered_users unban_account
unban_ip unregister
# 用法二:看单条命令的参数定义与示例
ejabberdctl help srg_create
实测回显(输出节选):
Command Name: srg_create
Arguments: group::binary : Group identifier
host::binary : Group server name
label::binary : Group name
description::binary : Group description
display::[ group::binary ] : List of groups to display
Example: ejabberdctl srg_create "group3" "myserver.com" "Group3" "Third group" "group1","group2"
Tags: shared_roster_group v1
# 用法三:glob 模糊查命令(列出所有 backup 相关命令)
ejabberdctl help *backup*
实测回显(输出节选):
backup
install_fallback
...
💡 说明:
help <命令名>的 Arguments 段是参数顺序的权威定义——ejabberdctl 报参数错误时第一动作就是回来看它。列表型参数用,分隔、元组用:分隔(help 输出开头有说明)。
三、前置条件
- ejabberd 26.09 已部署并在跑(部署见同系列部署篇);
- 执行机可访问主节点的 Erlang 分布式端口(EPMD 4369 与节点分布口;同机部署天然满足,远程执行需打通并一致配置 cookie——见集群域注意事项);
- 管理命令无需输入密码:本机 ejabberdctl 的授权由配置
api_permissions的console commands条目控制(默认from: ejabberd_ctl, who: all, what: "*"全放行;收紧方法见配置详解篇 5.9 节)。
验证服务可达(所有后续命令的前提):
docker exec ejabberd-26.09-main ejabberdctl status
实测回显:
The node ejabberd@main is started with status: started
ejabberd 26.9.0 is running in that node
四、节点运维域
本域命令管理服务自身生命周期与运行时状态,是巡检与变更的基础。
4.1 status:服务状态
ejabberdctl status
实测回显:
The node ejabberd@main is started with status: started
ejabberd 26.9.0 is running in that node
节点未启动时的对照回显(实测停止服务后执行):
Failed RPC connection to the node ejabberd@main: nodedown
Commands to start an ejabberd node:
start Start in server mode
foreground Start in server mode (attached)
...
nodedown 提示块自带启动指引,巡检脚本可直接以 status 退出码判断健康(started 时退出码 0)。
4.2 start / stop / restart:生命周期
ejabberdctl start # 后台启动节点
ejabberdctl stop # 停止节点(等价优雅停机,在线会话断开)
ejabberdctl restart # 重启节点(同节点名重启,Mnesia 状态保留)
实测要点:stop 后 status 立即转 nodedown;restart 会先停后起,监听端口有数秒空窗。容器部署下更常用 docker compose restart ejabberd(效果等同重启整个工作负载),二进制安装/systemd 部署则直接用这三条。
4.3 stop_kindly / restart_kindly:优雅批量通知
这两条命令先给所有在线用户广播通知并等待,再执行停机/重启,适合计划内变更:
ejabberdctl help stop_kindly
实测回显(输出节选):
Command Name: stop_kindly
Arguments: delay::integer : Number of seconds
announcement::string : Announcement to send
...
4.4 get_loglevel / rotate_log:日志级别与轮转
ejabberdctl get_loglevel
实测回显:
info
ejabberdctl rotate_log
实测回显:命令无输出、退出码 0,立即触发一轮日志文件轮转。改级别用配置篇的 loglevel 参数 + reload_config(实测闭环见配置详解篇 3.2 节)。
五、账号管理域
本域命令覆盖账号全生命周期:注册、验证、改密、封禁、注销、清理。所有命令带 user 与 host(域名)两个定位参数。
5.1 register / registered_users:注册与列出
ejabberdctl register alice localhost alice12345
ejabberdctl register bob localhost bob123456
ejabberdctl registered_users localhost
实测回显:
User alice@localhost successfully registered
User bob@localhost successfully registered
admin
alice
bob
ops
registered_users 每行一个账号名(不含域名)。账号存储后端决定数据落点:默认 Mnesia;配置切换 SQL 后账号写 SQL 库——实测切换 SQLite 后 registered_users 只列 SQL 侧账号(对照实验见配置详解篇 5.7 节)。
5.2 check_password / check_account:验证
ejabberdctl check_password alice localhost alice12345
echo "exit=$?"
ejabberdctl check_password alice localhost wrongpass
echo "exit=$?"
实测回显:
exit=0
Error: false
exit=1
要点:密码正确无任何输出、退出码 0;错误输出 Error: false、退出码 1——脚本判断以退出码为准。check_account <user> <host> 只检查账号存在性(实测存在账号退出码 0),check_password_hash 则接受哈希值比对(避免明文出现在命令行)。
5.3 change_password:改密
ejabberdctl change_password bob localhost bob999999
ejabberdctl check_password bob localhost bob999999
echo "exit=$?"
实测回显:
exit=0
改密成功无输出;用 check_password 以新密码验证退出码 0 即闭环。WebAdmin 忘记管理口令时就是这条命令救场。
5.4 ban_account / unban_account / list_banned:封禁体系
ejabberdctl ban_account bob localhost '违规测试封禁'
ejabberdctl list_banned localhost
ejabberdctl unban_account bob localhost
ejabberdctl list_banned localhost
echo "after-unban exit=$?"
实测回显:
bob@localhost
after-unban exit=0
ban_account 立即踢掉该账号全部在线会话并拒绝新登录(第二参数是封禁原因文本,会写进账号属性);list_banned 输出封禁名单(封禁中显示 bob@localhost,解封后为空);unban_account 解封。相关补充命令:get_ban_details(看封禁原因与时间)、count_banned(计数)、unban_ip(解封 IP)。
5.5 unregister:注销账号
ejabberdctl unregister tester localhost
ejabberdctl registered_users localhost
实测回显(注销 tester 后):
admin
alice
bob
ops
注销立即删除账号及其离线数据;在线会话同时被踢。批量清理僵尸账号用 delete_old_users <天数> <域>(删除超过 N 天未登录的账号,属高危操作,先 backup 再执行)。
5.6 vcard:用户名片读写
ejabberdctl set_vcard2 alice localhost N GIVEN 'Alice-Zhang'
ejabberdctl get_vcard2 alice localhost N GIVEN
实测回显:
Alice-Zhang
set_vcard2/get_vcard2 按「vCard 字段路径」操作(N GIVEN = Name → Given name;TEL NUMBER = 电话号码);字段名与 vCard 标准字段一致。整张名片导出用 get_vcard <user> <host> <name>(需指定单字段)——注意 26.09 的 get_vcard 必须带字段名,不带参数会打印 help(实测)。
六、集群域
本域命令管理多节点集群的组建与观察。实测环境为双节点:ejabberd@main(主)+ ejabberd@replica(副),两节点同名 cookie、各自独立 Mnesia spool 目录。
6.1 join_cluster:把本节点加入集群
在要加入的新节点上执行,参数是已有集群成员的节点名:
# replica 节点上执行
ejabberdctl join_cluster ejabberd@main
实测回显:
Trying to join that cluster, wait a few seconds and check the list of nodes.
加入后 Mnesia 数据自动同步——主节点注册的账号在副节点立即可见(实测:main 注册 admin 后,replica 执行 registered_users localhost 输出 admin)。
6.2 list_cluster / list_cluster_detailed:集群成员
ejabberdctl list_cluster
实测回显(双节点):
ejabberd@replica
ejabberd@main
ejabberdctl list_cluster_detailed
实测回显:
ejabberd@main true The node ejabberd@main is started. Status: started
ejabberd 26.9.0 is running in that node 0 439 45 none
ejabberd@replica true The node ejabberd@replica is started. Status: started
ejabberd 26.9.0 is running in that node 0 438 45 none
逐列说明:节点名 → 是否在线(true/false)→ 节点状态描述 → 三个运行指标(会话数/进程数等)→ master 角色。巡检脚本读这一条即可拿到全集群健康度。
6.3 get_master / set_master:master 角色
ejabberdctl get_master
实测回显:
none
ejabberdctl set_master ejabberd@main
实测回显:
ok
get_master 返回 none 表示未显式指定 master(默认各节点对等,按 Mnesia 表类型自动处理写冲突);set_master 显式钦定主节点,适合「多写冲突时以谁为准」的场景。
6.4 join_cluster_here:反向拉节点
与 join_cluster 方向相反:在老成员上执行,把指定节点拉进集群:
# main 上执行
ejabberdctl join_cluster_here ejabberd@replica
实测回显(replica 已在集群时):
Error: error
Error: "This node already joined that running node."
报错本身验证了幂等保护:目标节点已在集群时拒绝重复加入。
6.5 leave_cluster:退出集群(实测受限,见注意事项)
ejabberdctl leave_cluster <节点名>
实测情况:在双节点集群上分别尝试 leave_cluster ejabberd@replica(main 上踢副节点)、leave_cluster ejabberd@main(副节点指主节点)、leave_cluster ejabberd@replica(自指)三种姿势,均返回错误:
Error: {badrpc,nodedown}
而同时刻两个节点的 registered_users/list_cluster RPC 全部正常(ping 为 pong)。实测结论:26.09 在该环境(短节点名 + 双节点 compose 网络)下 leave_cluster 存在可用性限制。实践退集路径(实测可行):
- 直接停掉要退出的节点(
docker compose stop ejabberd-replica或系统层ejabberdctl stop); - 存活节点
list_cluster自动收敛(实测停掉 replica 后 main 上只剩ejabberd@main); - 节点重启后会凭 Mnesia 中保留的集群成员关系自动回归集群(实测 replica 重启后未再 join 即重新出现在 main 的 list_cluster 中),若需真正脱离集群则清空其 spool 目录重建。
6.6 集群域注意事项
- 各节点 cookie 必须一致(容器部署用
ERLANG_COOKIE环境变量,二进制部署写在ejabberdctl.cfg的ERLANG_COOKIE);cookie 不一致时 join 报「cannot reach that node」类错误; - 节点名的 host 部分必须可解析:实测节点名
ejabberd@replica而容器主机名不是replica时,本节点 ejabberdctl 都会 pang——节点名 host 部分要与主机名/网络别名一致; - 共享 Mnesia spool 目录是错误做法:实测 replica 挂载主节点 database 目录启动即报
Erlang node name mismatch: I'm running in node [ejabberd@replica], but the mnesia database is owned by [:ejabberd@localhost]——每个节点必须独立 spool 目录,数据靠集群同步而非共享盘。
七、备份迁移域
本域命令覆盖「单库备份恢复」与「Mnesia → SQL 迁移导出」两条线。
7.1 backup / restore:Mnesia 整库备份
ejabberdctl backup /opt/ejabberd/database/ejabberd-backup.backup
实测回显:无输出即成功,宿主侧确认产物:
-rw-r--r-- 1 9000 9000 21758 10月 21 17:08 /srv/ejabberd/database-main/ejabberd-backup.backup
ejabberdctl restore /opt/ejabberd/database/ejabberd-backup.backup
ejabberdctl registered_users localhost
实测回显(恢复后账号完整):
admin
alice
bob
ops
要点:backup 是 Mnesia 二制镜像(含账号、名册、vCard、房间等全部表);restore 会把备份内容合并覆盖进当前库;备份路径写容器内视角路径时注意落到挂载卷,否则文件留在容器层(重建即失)。
7.2 install_fallback:备份转热备
install_fallback <文件> 把备份文件注册为 Mnesia 的 fallback 数据——节点以空库冷启动时自动用该备份恢复。迁移换机场景的组合拳:旧机 backup → 新机装好 ejabberd → install_fallback → 启动即得全部数据。
7.3 export_db:导出为 SQL(迁移主通道)
export_db <域名> <目录> 把某域数据序列化为 SQL 文件(每模块一个 .dbser 文件),供 import_db 导入 SQL 后端:
ejabberdctl export_db localhost /opt/ejabberd/database/export
实测回显(目录不存在时失败):
Operation failed after exporting 0 records with error Unable to open file /opt/ejabberd/database/export/localhost_ejabberd_auth.dbser for write: enoent
预建目录后重试(实测):
mkdir -p /opt/ejabberd/database/export
ejabberdctl export_db localhost /opt/ejabberd/database/export
ejabberdctl export_db_status localhost
实测回显:
Export started
Operation was completed after exporting 1 records: 'Serialization finished for modules: ejabberd_auth, mod_mam, mod_pubsub, mod_muc, mod_privacy'
产物确认(实测目录清单节选):
-rw-r--r-- 1 ejabberd ejabberd 79 Oct 21 09:20 localhost_ejabberd_auth.dbser
-rw-r--r-- 1 ejabberd ejabberd 0 Oct 21 09:20 localhost_mod_mam.dbser
要点:目标目录必须预先存在(实测 enoent 失败样本);导出异步执行,export_db_status <域> 查询进度;配套命令 import_db(导入到 SQL 后端)、export_db_abort(中止)、import_db_status(导入进度)。迁移完整流程:源库 export_db → 目标装好 SQL 后端 → import_db → registered_users 核对。
7.4 mnesia_change / mnesia_change_nodename:改库属主节点名
ejabberdctl help mnesia_change
实测回显(输出节选):
Arguments: old_node_name::string : Old erlang node name
Result: res::rescode
换主机名/换节点名后旧 Mnesia 库「属主」仍是老节点名,服务启动会报 node name mismatch(集群域 6.6 实测复现过该报错),用 mnesia_change <老节点名>(新节点名自动推断)或四参数形态 mnesia_change_nodename <老节点> <新节点> <老备份> <新备份> 转换。
7.5 print_sql_schema:SQL 建表参考
ejabberdctl print_sql_schema mssql
输出各 SQL 方言(mssql/mysql/pgsql/sqlite)的完整建表 DDL,手工初始化外部库或 DBA 审批建表语句时直接引用。镜像内另附全量 SQL 文件(/opt/ejabberd/sql/ 下 mysql.sql、pg.sql、lite.sql 等实测在列)。
八、诊断排障域
本域命令回答「现在谁在线、系统什么状态、历史何时活跃」三类问题。
8.1 stats / connected_users:会话与统计
ejabberdctl stats registeredusers
ejabberdctl stats onlineusers
ejabberdctl connected_users_number
ejabberdctl connected_users
实测回显:
4
0
0
(connected_users 无在线用户时输出空行。)stats <指标名> 支持的常用指标:registeredusers、onlineusers、totalxmppfiletransferssent 等;无人在线时 connected_users 输出为空属正常。客户端登录后:
ejabberdctl connected_users
ejabberdctl user_resources alice localhost
connected_users 每行一个 user@host/resource 会话标识(多端登录多行);user_resources 列某用户全部在线 resource。
8.2 get_last:最后活跃时间
ejabberdctl get_last alice localhost
实测回显:
2026-10-21T09:18:13.486219Z NOT FOUND
两列:时间戳 + 状态(NOT FOUND 表示该用户从未建立过会话;在线用户返回 online,离线用户返回 offline)。
8.3 srg:共享名册组(企业通讯录)
ejabberdctl srg_create ops-team localhost 运维组 '运维团队共享名册' ''
ejabberdctl srg_list localhost
ejabberdctl srg_user_add admin localhost ops-team localhost
ejabberdctl srg_user_add alice localhost ops-team localhost
ejabberdctl srg_get_info ops-team localhost
实测回显(srg_get_info):
ops-team
label 运维组
displayed_groups []
description 运维团队共享名册
要点:第五参数 display(显示组列表)传空串 '' 可创建独立组;传不存在的组名实测报 Error: {wrong_displayed_groups,[<<"team-a">>]}——display 引用的组必须先存在。成员互见靠共享名册(mod_shared_roster),适合按部门拉通讯录。配套:srg_user_del(移成员)、srg_delete(删组)。
8.4 MUC:群聊房间管理
ejabberdctl create_room ops-room conference.localhost localhost
ejabberdctl muc_online_rooms conference.localhost
实测回显:
ops-room@conference.localhost
create_room 回显完整房间 JID;房间未被使用时 muc_online_rooms 输出空(持久房间配置在库、房间进程按需实例化)。配套命令族:destroy_room(销毁)、rooms_unused_list <MUC服务> <天数>(清理闲置房)、muc_register/muc_unregister(房间注册名)。实测踩坑:create_room 的第二参数是 MUC 服务 host(conference.localhost),误传 localhost 报 Unknown host passed in 'serverhost'。
8.5 mnesia_info_ctl:内置库诊断
ejabberdctl mnesia_info_ctl
实测回显(输出节选):
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
排查 Mnesia 层异常(锁等待、未决事务)的专用命令;配合 ejabberdctl debug(附到节点的 Erlang 交互 shell,执行 mnesia:info(). 可看全量表清单)做深度诊断。
九、注意事项
- 命令授权来自配置:ejabberdctl 免密全放行依赖
api_permissions的console commands条目;生产若收紧该条目,相应命令会报权限拒绝——先查配置再查命令本身; - 路径写挂载卷:backup/export 的输出路径若不在持久化卷内,容器重建即失(实测路径习惯见部署篇);
- 高危命令先备份:
delete_old_users、destroy_room、restore均不可逆,执行前ejabberdctl backup; - 异步命令查状态:export/import 类命令立即返回 "started",用对应
_status命令确认完成; - 远程执行:在管理机上装 ejabberdctl 远程操作集群时,需与本端配置一致 cookie 与网络互通(官方 CONTAINER.md 提供
ERL_DIST_PORT=5210固定分布口的替代方案)。
十、常见问题(FAQ)
Q1:所有命令都报 Failed RPC connection to the node ejabberd@main: nodedown?
三层排查(实测经验序):① 服务真没起——status/日志确认,先 ejabberdctl start;② 节点名 host 部分不可解析——实测节点名 ejabberd@replica 与主机名不符时本机都 pang,对齐主机名解决;③ cookie 不一致——对比各节点 cookie 文件/环境变量。容器内 ps aux | grep beam 看 -sname 参数值可确认节点名实况。
Q2:join_cluster 报 "This node cannot reach that node."?
目标节点名解析问题:实测 replica 解析 ejabberd@main 时若 main 名不在网络层可达(或被自身 hosts 指到 127.0.0.1)即报此错。解法:节点名 host 部分使用容器/主机网络别名并保证互通,cookie 两端一致。
Q3:export_db 报 Unable to open file ... enoent?
目标目录不存在——export 不会自建目录(实测样本见 7.3 节),先 mkdir -p 再导出。
Q4:srg_create 报 wrong_displayed_groups?
第五参数 display 引用了不存在的组(实测 team-a 不存在时报 {wrong_displayed_groups,[<<"team-a">>]})。独立组传空串 '',组间互见先建被引用组。
Q5:create_room 报 Unknown host passed in 'serverhost'?
第二参数要传 MUC 服务 host(默认 conference.<域名>)而非服务器域名本身。
Q6:module_install 报 conflict?
模块已装过(首次安装的编译 Warning 输出容易让人误判失败)。用 modules_installed 查已装清单、module_uninstall 卸载后重装;模块配置文件落在 .ejabberd-modules/<模块名>/conf/ 下。
十一、参考链接
- 官方 ejabberdctl 管理文档:https://docs.ejabberd.im/admin/guide/managing/
- 官方 API 命令总表(ejabberdctl/REST/WebAdmin 同池):https://docs.ejabberd.im/developer/ejabberd-api/admin-api/
- 官方集群指南:https://docs.ejabberd.im/admin/guide/clustering/
- 官方迁移与备份文档:https://docs.ejabberd.im/admin/guide/managing/#change-computer-hostname
- 官方容器部署文档(集群环境变量与 ERL_DIST_PORT):https://github.com/processone/ejabberd/blob/master/CONTAINER.md
- 同系列部署篇:《Docker Compose 部署 ejabberd 指南》
- 同系列配置篇:《ejabberd 26.09 配置参数详解》
- 版本来源:https://github.com/processone/ejabberd/releases.atom(26.09,查询日期 2026-10-21)