必须先用rabbitmqctl version查清RabbitMQ精确版本,下载严格匹配的.ez插件;复制到正确plugins目录并设置rabbitmq属主权限;启用时不带版本号和.ez后缀;Docker禁用全量plugins挂载,推荐自定义镜像或运行时注入。

查清 rabbitmqctl version 再下载插件
插件和 RabbitMQ 主版本号必须严格一致,比如 rabbitmqctl version 输出 3.12.0,你就只能下 rabbitmq_delayed_message_exchange-3.12.0.ez。别信镜像 tag(如 rabbitmq:3.12)或 rabbitmq-server --version,它们可能漏掉补丁号,导致启用失败甚至容器崩溃。
去 GitHub Releases 页面:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases,找和 rabbitmqctl version 完全一致的 .ez 文件。3.12.x 插件在 3.11.x 上会报错:missing dependency: rabbitmq_server-3.12.0。
原生安装:复制、权限、启用三步缺一不可
插件放错路径或权限不对,rabbitmq-plugins enable 会静默失败——没报错但实际没生效。
- 先查真实插件目录:
rabbitmq-plugins directories,常见路径是/usr/lib/rabbitmq/lib/rabbitmq_server-3.12.0/plugins/ - 复制并设权:
sudo cp rabbitmq_delayed_message_exchange-3.12.0.ez /path/to/plugins/;然后sudo chown rabbitmq:rabbitmq /path/to/plugins/rabbitmq_delayed_message_exchange-3.12.0.ez;再sudo chmod 644 /path/to/plugins/*.ez - 启用命令里**不带版本号、不带 .ez**:
sudo rabbitmq-plugins enable rabbitmq_delayed_message_exchange - 重启服务:
sudo systemctl restart rabbitmq-server
Docker 环境:严禁 -v 挂载整个 plugins 目录
用 -v /host/plugins:/plugins 会覆盖 RabbitMQ 自带的核心插件(比如 rabbitmq_management),启动时报错:Failed to load module 'rabbit'。
推荐两种方式:
- 构建镜像:
COPY rabbitmq_delayed_message_exchange-3.12.0.ez /opt/rabbitmq/plugins/,再RUN rabbitmq-plugins enable rabbitmq_delayed_message_exchange - 运行时注入:
docker cp rabbitmq_delayed_message_exchange-3.12.0.ez container_name:/opt/rabbitmq/plugins/,进容器执行rabbitmq-plugins enable rabbitmq_delayed_message_exchange,再docker restart container_name
声明 x-delayed-message 交换机必须带参数
插件启用后,Web 管理界面的 Exchange 类型列表里会出现 x-delayed-message,但直接声明会失败——你必须显式指定 {"x-delayed-type":"direct"}(或其他合法类型,如 topic)。
发送消息时,不能用 delivery_mode 或 TTL,必须走 headers 带 x-delay 字段:
rabbitmqadmin publish exchange=delayed_exchange routing_key="my.queue" \
payload="hello" \
properties='{"headers":{"x-delay":10000}}'
注意:这个 x-delay 是毫秒值,且只对当前消息生效;交换机本身不保存延迟逻辑,全靠插件在 Mnesia 表中调度。
最容易被忽略的是:插件启用后,RabbitMQ 不会自动加载新交换机类型到所有 vhost,首次声明前最好确认目标 vhost 已启用该插件(rabbitmq-plugins list -v | grep delayed 显示 [E*] 表示已启用)。


















