Windows 安装 RabbitMQ 与 Erlang:版本匹配与启动排错
做 Windows 上的 RabbitMQ 部署十次里有八次卡住的不是消息队列本身而是 Erlang 那一层。我见过太多同事兴冲冲双击完 rabbitmq-server 的安装包结果 services.msc 里那个服务一启动就报 1067或者命令行敲rabbitmqctl status冷冰冰甩一句 unable to connect to node。这两类问题九成以上跟版本不匹配和 .erlang.cookie 有关跟 RabbitMQ 的功能没半点关系。这篇就把 windows 安装 rabbitmq 和 erlang 的完整过程摊开讲包括版本对应关系怎么查、安装路径怎么选、环境变量怎么配、启动失败怎么一步步排查。不管你是第一次接触消息队列的新手还是被 1067 折腾到想重装系统的老手按这个顺序走一遍基本能一次跑通。1. 先把版本对应关系捋清楚别等装完才发现不兼容很多人装 RabbitMQ 的顺序是搜到安装包下载双击报错。原因很简单RabbitMQ 是跑在 Erlang 虚拟机上的它对 Erlang 的版本范围卡得非常死高一个版本或者低一个版本都可能直接启动失败而且报错信息往往不指向真正的原因。所以在动手之前花五分钟确认版本组合能省掉后面一两个小时的排查。1.1 Erlang 和 RabbitMQ 的关系到底是什么把 RabbitMQ 想成一栋房子Erlang 就是地基和承重结构。RabbitMQ 本身是用 Erlang 写的运行的时候完全依赖 Erlang 的运行时环境ERTSErlang Runtime System和它的虚拟机BEAM。你在 Windows 上装的那个otp_win64_xx.x.exe装的就是 Erlang/OTP 这套运行环境它会提供erl.exe、erlc.exe、epmd.exe这些可执行文件。RabbitMQ 的服务本质上是一个 Erlang 节点节点名长这样rabbit你的主机名。启动服务的时候Windows 会去调 Erlang 的运行时把 RabbitMQ 的一堆 .beam 字节码文件加载进 BEAM 虚拟机跑起来。所以 Erlang 装不对RabbitMQ 连启动这一步都走不到。这里有个容易被忽略的点epmdErlang Port Mapper Daemon。它是 Erlang 的端口映射守护进程默认监听 4369。Erlang 节点之间通信、rabbitmqctl跟节点通信都要先通过 epmd 找到对方。你在 Windows 上跑netstat -ano | findstr 4369如果看到一个叫epmd.exe的进程占着说明 Erlang 那层已经在跑了。很多时候重启一下就好了的玄学问题其实是 epmd 里残留了旧的节点注册信息。1.2 版本对应速查表3.8 到 4.1官方在每个版本的 Release Notes 里都会标注支持的 Erlang 范围但翻起来麻烦。我把常用组合整理成一张表你按自己的 RabbitMQ 版本反查 Erlang 版本就行RabbitMQ 版本支持的 Erlang/OTP 范围建议选择4.1.x26.2 - 27.xErlang 26.2.54.0.x26.2 - 27.xErlang 26.2.53.13.x26.0 - 27.xErlang 26.2.53.12.x25.0 - 26.xErlang 25.3.23.11.x25.0 - 25.3Erlang 25.3.23.10.x24.3 - 25.xErlang 24.3.4.173.9.x23.2 - 24.xErlang 24.3.4.173.8.x21.3 - 23.xErlang 23.3.4.11这张表里几个规律值得记一下RabbitMQ 每个大版本基本只认相邻一到两个 Erlang 大版本。比如 3.11 只认 Erlang 25你装个 Erlang 24 上去服务启动时会报{init terminating in do_boot...}之类的错或者在日志里写RabbitMQ requires Erlang 25.0 or later。反过来装个 Erlang 26 配 3.11也会因为模块接口变化直接崩。注意不要追求都装最新版。最新的 RabbitMQ 配最新的 Erlang 有时候反而会因为发行时间差踩坑。稳妥做法是 RabbitMQ 选一个已经发布两三个月以上的稳定版Erlang 按上表选范围中段的版本。1.3 选版本的三条判断标准第一条看你的项目依赖。如果你用的是 Spring Boot 的spring-boot-starter-amqp看它默认带的 amqp-client 版本一般兼容 RabbitMQ 3.8 以上都没问题。如果你要用 MQTT 插件接物联网设备注意rabbitmq_mqtt插件在 3.12 之后有比较大的行为调整老教程里的配置不一定适用。第二条看操作系统位数和架构。现在基本都是 64 位下载otp_win64_xxx.exe和rabbitmq-server-x.x.x.exe。Windows Server 2016 及以上、Windows 10/11 都没问题。Windows 7 不要折腾了新版 Erlang 已经不提供支持。第三条看是不是内网环境。如果是不能联网的机器你得提前把两个安装包都下好带过去Erlang 的安装包大概 100 多 MBRabbitMQ 安装包 20 MB 左右。国内直接下 GitHub Releases 可能很慢可以找一些开源的镜像站转存的文件或者用公司内网的制品库Nexus、Artifactory代理一份。这一步在离线部署时最容易翻车——只下了 RabbitMQ 忘了下 Erlang到了现场干瞪眼。2. Erlang 安装路径、环境变量、验证一步都不能少Erlang 的安装过程本身不复杂但有几个细节决定了后面能不能顺利。我见过最典型的翻车是安装路径用了默认的C:\Program Files\erl-26.0带空格结果 RabbitMQ 服务启动时解析路径出错。另一个是把环境变量配成了ERLANG_HOMEC:\Program Files\erl-26.0\bin多写了个\bin后面一路报错。2.1 下载与安装过程中的关键勾选项打开 Erlang 官方下载页找到对应 OTP 版本的 Windows 64-bit installer文件名形如otp_win64_26.2.5.exe。双击运行之后安装向导里需要留意的有几个地方。第一个是安装目录。我一般改成D:\erl26或者C:\erl26这种短路径不放在Program Files下面。原因有两个一是路径里有空格某些老版本脚本处理不好二是 Windows 的 UAC 对Program Files有额外保护RabbitMQ 服务如果以 System 账户运行访问那里的文件有时会碰到权限上的麻烦。路径里也不要出现中文和任何符号。第二个是是否勾选添加到 PATH。部分版本的 OTP 安装程序会提供 Add Erlang to the PATH environment variable 类似的选项勾上省事但我建议不管勾没勾装完都手动去环境变量里确认一遍。因为安装程序有时候是往当前用户的 PATH 里写而 RabbitMQ 服务跑在系统账户下读不到用户的 PATH。第三个是Microsoft Visual C Redistributable。新版 Erlang 的运行需要 VC 运行库Windows 10/11 通常自带但如果你的 Windows Server 比较干净可能会缺。安装程序一般会检测并提示你先装按提示走就行。2.2 环境变量配置与三种验证方式装完之后配置环境变量。右键此电脑 → 属性 → 高级系统设置 → 环境变量在系统变量里操作新建ERLANG_HOME值填安装根目录比如D:\erl26。注意是根目录不带\bin。编辑Path追加一条%ERLANG_HOME%\bin。改完一定要重新开一个命令行窗口旧窗口读的还是老的环境变量这是很多人改了没用的原因。验证分三步从浅到深erl -version这条命令会输出 Erlang 虚拟机的版本信息能看到类似Erlang (SMP, ASYNC_THREADS) (BEAM) emulator version 13.x的内容。能看到说明 PATH 配对了。erl直接进入 Erlang shell会出现Eshell V13.x的提示符1。在这里你可以跑一行代码查 OTP 版本erlang:system_info(otp_release).会返回26这样的字符串这就是 RabbitMQ 关心的 OTP 大版本。退出输入halt().注意结尾那个点不能少这是 Erlang 的语法要求。第三种是查 epmd 是否正常epmd -names如果返回epmd: up and running on port 4369 with data:并且下面列着节点说明 Erlang 的端口映射守护进程工作正常。这时候还没有 RabbitMQ 节点列表是空的也正常只要不报连接错误就行。2.3 安装目录与路径命名踩坑记录这一节专门讲我踩过的坑都是文档里不会写的。坑一用户名带中文或空格。Windows 的用户目录是C:\Users\张三Erlang 的 cookie 文件会写在C:\Users\张三\.erlang.cookie。RabbitMQ 服务以系统账户跑读的是C:\Windows\System32\config\systemprofile\.erlang.cookie。两边路径都不一样内容还经常不一致直接导致rabbitmqctl连不上节点。这个后面第 4 章会详细讲怎么修。坑二装了两个 Erlang 版本。先装了个 Erlang 24 发现不兼容又装了个 Erlang 26旧的没卸。结果 PATH 里两条都有erl命令调到哪个全看顺序行为完全不可预测。升级 Erlang 之前先把旧的卸干净卸载完还要手动删残留目录和注册表中的 Erlang 项。坑三安装时中途取消。Erlang 安装程序被中断后注册表里可能留下了半截记录重新装同一个版本会提示已安装。这时候去控制面板删掉删不掉就用msiexec相关的清理方式处理或者选择装一个版本号稍微不同的包绕开。提示如果你打算在一台机器上长期维护 RabbitMQ建议把ERLANG_HOME和后面会提到的RABBITMQ_BASE都显式配好别依赖默认值。默认值在服务模式下的位置很分散出了问题找日志都费劲。3. RabbitMQ 安装与初始配置全流程Erlang 那层稳了RabbitMQ 的安装其实很快。Windows 版 RabbitMQ 提供的是 exe 安装包装完之后会自动把服务注册进 Windows 服务列表默认是自动启动。很多人装完发现服务起来了但网页打不开那只是管理插件没开不是安装失败。3.1 安装包安装与服务自动注册从 RabbitMQ 官方 Releases 页面下载rabbitmq-server-x.x.x.exe。双击运行安装向导基本一路下一步。有一点要注意安装程序会检测 Erlang。如果它找不到 Erlang会在安装过程中报错或者装完后服务起不来。所以务必先装 Erlang 并配好环境变量再装 RabbitMQ。如果你先装了 RabbitMQ 再补 Erlang装完 Erlang 之后重新启动一下 RabbitMQ 服务甚至重装一次安装包让它重新写服务配置会比较稳。安装完成后打开services.msc往下找到名为RabbitMQ的服务。状态应该是正在运行启动类型自动。如果没有自动启动右键启动一次。命令行也可以net start RabbitMQ启动之后立刻验证节点状态rabbitmqctl status这条命令会输出一大堆信息Erlang 版本、RabbitMQ 版本、节点名、监听端口、内存和磁盘水位、文件描述符限制等等。能正常输出就是最大的成功信号说明 Erlang、cookie、节点注册这三关全过了。几个关键字段值得看Node name形如rabbitDESKTOP-XXXX前面固定是 rabbit后面是你的主机名。Erlang version确认和表里要求的一致。Listeners会列出 5672AMQP、25672集群等端口。3.2 启用管理插件与 Web 控制台首次登录默认安装完只有 AMQP 协议可用Web 管理台是关着的需要手动开插件rabbitmq-plugins enable rabbitmq_management执行完会提示The following plugins have been enabled并列出rabbitmq_management及其依赖。插件是持久化生效的重启服务后依然开着不用每次开。然后浏览器访问http://localhost:15672默认账号密码都是guest。登录进去能看到 Overview、Connections、Channels、Queues 等标签页。这里有个面试常问也常踩的点guest 用户默认只能从 localhost 登录。你在服务器上装完从自己电脑访问服务器 IP 的 15672会看到登录页面但永远登不进去提示 Login failed。这不是密码错了是 guest 的访问限制loopback_users。正确做法是新建一个业务用的管理员账户而不是去改 guest 的限制——生产环境放开 guest 是非常糟糕的做法。如果连登录页面都打不开按顺序检查插件是否真的启用rabbitmq-plugins list看rabbitmq_management前面是不是[E*]、15672 端口是否被占用netstat -ano | findstr 15672、Windows 防火墙是否放行了 15672。3.3 用户、vhost、权限分配实操生产环境第一件事就是建独立用户和 vhost别用 guest。三条命令搞定rabbitmqctl add_user appuser YourStrongPwd123 rabbitmqctl set_user_tags appuser administrator rabbitmqctl set_permissions -p / appuser .* .* .*解释一下第三条命令里三个.*的含义这是最容易搞混的地方。set_permissions -p vhost user 配置权限 写权限 读权限三个正则分别对应配置权限configure能对哪些队列/交换机做创建、删除操作。写权限write能往哪些队列/交换机发消息。读权限read能从哪些队列消费消息。.*表示全部允许。如果你想让某个用户只能操作以order.开头的队列可以写成^order\..*。正则用的是 Erlang 的 re 语法和常见正则基本一致但转义规则略有差异写复杂正则前先在脑子里确认一下。多租户场景下建议按业务建 vhostrabbitmqctl add_vhost /order rabbitmqctl set_permissions -p /order orderuser .* .* .*vhost 相当于逻辑隔离的命名空间不同 vhost 里的同名队列互不干扰。新加的 vhost 默认权限是空的任何用户不配权限都连不进去这个坑很多人会踩——Connection 一直建不起来日志里看是ACCESS_REFUSED。查看用户列表用rabbitmqctl list_users查看权限用rabbitmqctl list_permissions -p /。注意rabbitmqctl在 Windows 上必须以管理员身份运行命令提示符否则会报节点连接失败或权限不足。而且尽量用 cmd 而不是 Git Bash因为脚本里的路径处理方式不一样Git Bash 下经常会因为路径转换问题报错。3.4 开启 MQTT 插件并用 MQTTX 联调如果你的场景是物联网设备上云或者前端/移动端想直连消息队列MQTT 插件会派上用场rabbitmq-plugins enable rabbitmq_mqtt默认 MQTT 监听 1883 端口。如果浏览器里也想用 MQTT over WebSocket再开一个rabbitmq-plugins enable rabbitmq_web_mqttWebSocket 默认走 15675 端口另外还有一个较新的rabbitmq_web_mqtt_examples可以开出一个测试页面。用 MQTTX 连接的时候填这几个参数地址localhost跨机就用服务器 IP端口1883用户名密码用你刚建的那个 appuserClient ID 随便填一个唯一的字符串。连上之后订阅一个 topic比如test/topic再往同一个 topic 发消息看能不能收到。MQTTX 联调常见的两个问题一是用户名密码留空MQTT 插件虽然允许匿名但取决于anonymous_login_user配置默认情况下匿名是被禁的会直接断开二是topic 用了$开头$SYS之类是系统保留的普通用户发不进去。还有个细节是同一 Client ID 重复连接会导致前一个被踢掉调试时两个窗口用同一个 ID 会互相打架。4. 启动失败与常见报错逐个拆解前面一路顺利的读者可以跳过这章但凡你在rabbitmqctl status那里卡住了这章就是给你准备的。我把 Windows 上最常遇到的几类问题按报错现象 → 根因 → 处理方式的结构讲清楚。4.1 服务启动 1067 与 .erlang.cookie 不一致现象services.msc 里启动 RabbitMQ弹窗报错误 1067进程意外终止或者rabbitmqctl status报Error: unable to perform an operation on node rabbitxxx. Please see diagnostics information and suggestions below.根因Erlang 节点之间通信需要共享一个 cookie 字符串叫.erlang.cookie。RabbitMQ 服务跑在系统账户下它的 cookie 在C:\Windows\System32\config\systemprofile\.erlang.cookie而你在 cmd 里敲rabbitmqctl时用的是当前用户的 cookieC:\Users\你的用户名\.erlang.cookie这两个文件如果内容不一致命令行工具就连不上服务里的节点表现出来就是各种 unable to connect to node。处理方式把两个文件打开是隐藏文件要在资源管理器里开启显示隐藏文件把里面的字符串复制成完全一样。我一般的做法是以服务那份为准覆盖用户目录那份copy C:\Windows\System32\config\systemprofile\.erlang.cookie C:\Users\%USERNAME%\.erlang.cookie /Y复制完重新开一个管理员 cmd再跑rabbitmqctl status。如果还是连不上检查 Erlang 的版本是否在支持范围内——版本不兼容也会报非常相似的错误。还有一种情况是 cookie 文件的权限问题。用户目录那份如果被设成了只读或者当前用户没有读取权限也会读不到。右键属性 → 安全确认当前用户有读取权限。顺带说个更彻底的方案给 RabbitMQ 显式指定一个统一的 base 目录把 cookie、日志、mnesia 数据都放一起避免在系统目录里到处找。设置系统环境变量RABBITMQ_BASE D:\RabbitMQData设置完重启服务。之后日志会出现在D:\RabbitMQData\log数据库在D:\RabbitMQData\db管理起来清爽很多。这个变量在排查问题时价值极高强烈建议一开始就配上。4.2 端口占用、主机名与磁盘空间端口占用。RabbitMQ 相关端口有一串4369epmd、5672AMQP、25672集群通信、15672管理台、1883MQTT、15675MQTT WebSocket。任何一个被占都可能让服务起不来或功能异常。排查netstat -ano | findstr :5672 netstat -ano | findstr :15672找到 PID 之后用tasklist | findstr PID看是哪个进程。5672 被占用最常见的原因是之前装过一个 RabbitMQ 没卸干净另一个实例还在跑。解决办法是先停掉旧服务或者直接换个端口。改端口可以通过配置文件。在RABBITMQ_BASE目录下新建rabbitmq.conflisteners.tcp.default 5673 management.tcp.port 15673注意新版用的是.conf格式sysctl 风格老版本的rabbitmq.configErlang term 格式已经废弃了。网上一堆老教程还在教你写rabbitmq.config照抄会不生效这是个大坑。主机名问题。RabbitMQ 节点名依赖主机名。如果 Windows 的主机名包含中文、下划线或者特殊字符节点启动会报错类似Cant set short node name或nodedown。检查主机名hostname如果确实有问题去系统属性 → 计算机名里改成纯英文数字和连字符重启机器。主机名改了之后之前 mnesia 里存的旧节点数据会对不上可能需要清理RABBITMQ_BASE\db目录重新初始化所以最好在装之前就把主机名定好。磁盘空间。RabbitMQ 有个disk_free_limit默认行为是当磁盘剩余空间低于阈值通常是 50MB 或某个相对值时会阻塞所有生产者日志里能看到disk_free_limit set to ...和low disk watermark的告警。服务本身不会崩但消息发不进去表现得很诡异。用rabbitmqctl status看 Disk free limit 那一行或者查日志确认。解决办法就是清磁盘或者调整阈值rabbitmqctl set_disk_free_limit 1GB提示在测试机或者 C 盘空间紧张的机器上这个磁盘水位问题出现频率相当高。看到生产者莫名被阻塞第一反应应该是去查磁盘而不是怀疑代码。4.3 日志定位方法与常见问题速查表不知道日志在哪排查就是盲人摸象。RabbitMQ 的日志默认位置Windows 服务模式下C:\Users\你的用户名\AppData\Roaming\RabbitMQ\log如果配了RABBITMQ_BASE就变成RABBITMQ_BASE\log。服务以系统账户跑的时候还可能落在C:\Windows\System32\config\systemprofile\AppData\Roaming\RabbitMQ\log同一个目录下有一个rabbit主机名.log和一个同名.1的滚动日志直接看.log最新的那份。搜索error、crash、failed关键字。把常见问题整理成速查表遇到先对号入座报错现象大概率根因处理方式服务 1067启动即停Erlang 版本不匹配 / ERLANG_HOME 未配 / 路径含空格核对版本表检查系统变量换短路径重装unable to connect to node两边 .erlang.cookie 不一致统一 cookie 内容管理员身份重开 cmd管理台打不开端口无响应管理插件未启用 / 15672 被占 / 防火墙rabbitmq-plugins enable rabbitmq_management查端口guest 登录失败guest 仅限 localhost 访问新建管理员用户不要放开 guestACCESS_REFUSED - login was refused用户没有对应 vhost 的权限rabbitmqctl set_permissions -p vhost ...生产者被阻塞磁盘低于 disk_free_limit / 内存水位触发清磁盘或调阈值查rabbitmqctl status节点名含非法字符主机名有中文/下划线改主机名并重启必要时清理 db 目录rabbitmqctl报路径错误用了 Git Bash 而非 cmd改用管理员 cmd 执行配置文件改了不生效写成了老的 rabbitmq.config改用 rabbitmq.conf放对目录5. 卸载重装与长期维护的注意事项装不好想推倒重来的时候卸载这一步如果做不干净重装后会出现更诡异的问题——新老配置打架、注册表残留、旧节点数据被加载。我见过重装三次都失败的最后发现是 mnesia 数据目录没删。5.1 干净的卸载顺序正确的顺序是先停服务、先卸 RabbitMQ、再卸 Erlang反过来卸会留下悬挂的服务项。第一步停服务并移除服务注册net stop RabbitMQ sc delete RabbitMQ第二步控制面板卸载 RabbitMQ。卸完手动删残留目录可能的位置有C:\Program Files\RabbitMQ ServerC:\Users\用户\AppData\Roaming\RabbitMQ存着日志、mnesia 数据、配置C:\Users\用户\AppData\Roaming\RabbitMQ\db如果你配过RABBITMQ_BASE把这个目录也清掉第三步卸载 Erlang。控制面板里找到 Erlang OTP卸载之后删残留目录C:\Program Files\erl*或者你自己装的那个D:\erl*。第四步清理 cookie 和注册表。删掉C:\Users\用户\.erlang.cookie C:\Windows\System32\config\systemprofile\.erlang.cookie注册表可以打开regedit检查HKEY_LOCAL_MACHINE\SOFTWARE\Ericsson\Erlang有没有残留项有就删操作注册表前先导出备份这是基本素养。环境变量里的ERLANG_HOME、RABBITMQ_BASE也一并删掉。做完这四步再重装基本就是全新环境。5.2 长期运行的几个配置建议把 RABBITMQ_BASE 固定下来。前面提过这是让所有运行数据集中管理的关键。日志、mnesia、cookie 都在一个目录下备份和排查都方便。备份 RabbitMQ 的时候本质上是备份 mnesia 数据、配置文件和用户信息用户信息存在 mnesia 里不是单独的配置文件所以要导出的话得用rabbitmqctl相关命令或直接备份整个 db 目录注意先停服务。内存水位别乱调。vm_memory_high_watermark默认是 0.4意思是 Erlang 虚拟机占用超过物理内存 40% 就阻塞生产者这是保护机制不是 bug。在小内存的测试机上这个值容易触发表现为发着发着就不动了。可以适当调到 0.6但不建议调得更高Blocked 总比 OOM 崩溃好。开启日志轮转和监控。RabbitMQ 的日志会持续增长长期运行的机器上配置好日志大小和保留份数。配置文件里可以设log.file.level和轮转参数。生产环境建议接入监控看队列堆积、连接数、消息速率这几个核心指标。定期检查用户和权限。离职人员建的账户要清理用rabbitmqctl list_users过一遍。开发测试用的高权限账户不要带去生产。最后说个实操细节关于管理台的强密码策略。RabbitMQ 默认不强制密码复杂度add_user设个123456也能成功但这在暴露了 15672 的机器上非常危险。现在管理台登录有重试限制默认 3 次失败后延迟响应但仍然建议用强密码。我自己习惯是生成一串 20 位随机字符存到密码管理工具里。我在实际部署中最大的体会是Erlang 和 RabbitMQ 的安装过程难点从来不在安装本身而在两个地方的路径和身份的错位——一是安装路径和主机名里的非法字符二是系统账户与用户账户之间 cookie 和配置文件位置的不一致。把这两个错位想明白了Windows 上装 RabbitMQ 其实比很多人想象的要稳。装完之后别急着开发先花十分钟把用户、vhost、权限、日志路径和RABBITMQ_BASE这几件事理顺后面能少熬好几个夜。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →