ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows 安装 RabbitMQ:Erlang OTP 匹配与启动排查

Windows 安装 RabbitMQ:Erlang OTP 匹配与启动排查 在 Windows 上装 RabbitMQ十个新手里有八个会卡在同一个画面服务装完了net start一执行就提示启动失败或者浏览器输localhost:15672死活转圈。这事儿跟 RabbitMQ 本身关系不大八成是 Erlang 那个“隐形底座”没摆正。RabbitMQ 是用 Erlang 写的运行时完全依赖 OTP 环境Windows 上又没有包管理器帮你自动解决依赖所以版本对不对、环境变量指没指对、服务以哪个账号身份跑全都得自己扛。这篇就把 Windows 下 Erlang RabbitMQ 的安装、版本对应、服务注册、启动失败的排查链路一次性讲透从完全没接触过的同学到被 nodedown 折磨过的老手都能对照着找到自己那一步。1. Erlang 与 RabbitMQ 的版本对应关系为什么要放在第一步讲1.1 一张表看懂兼容矩阵很多人习惯先把 RabbitMQ 下载了安装时提示“检测不到 Erlang”再回头找 Erlang随手搜个官网最新版装上结果服务启动直接报错。问题就出在 Erlang/OTP 的大版本跟 RabbitMQ 有硬绑定不是“越新越好”。RabbitMQ 的官方文档里有一张兼容性列表核心区间大致如下版本一直在往前走装之前务必去官方文档核对一遍当前最新的对应关系RabbitMQ 版本建议的 Erlang/OTP 区间备注4.0.xOTP 26.2 及以上对 OTP 26 的早期小版本有要求别用 26.03.13.xOTP 26.x已经不再支持 OTP 253.12.xOTP 25.x / 26.x兼容面最宽老项目升级首选3.11.xOTP 25.x部分小版本支持 24.3不少线上系统还停在这一档3.10.xOTP 24.x / 23.3比较老的组合新项目不建议再用3.9.xOTP 24.x / 23.3同上看起来只是个数字游戏但背后是实打实的 API 变更。Erlang 的进程字典、inet模块、crypto库在 OTP 25、26 之间都有过调整RabbitMQ 内部大量使用这些底层能力。用高版本 OTP 去跑低版本 RabbitMQ最常见的结果不是装不上而是装上了、服务也能起但跑到某个特定功能比如 TLS 握手、集群间通信、消息持久化落盘的时候崩掉日志里给的堆栈还特别难读。反过来低版本 OTP 跑高版本 RabbitMQ往往连启动阶段都过不去。1.2 一个真实的反直觉场景我遇到过不止一个人这么干电脑上原先装过 OTP 24后来为了别的项目升到了 OTP 26接着去装 RabbitMQ 3.11.x安装向导一路下一步最后服务启动失败日志里全是{error,{badmatch,...}}之类的信息。他以为是 RabbitMQ 坏了重装了三遍。实际上就是 OTP 26 跟 RabbitMQ 3.11 不匹配把 Erlang 降回 OTP 25什么都没改服务立刻就起来了。所以建议的做法是这样先确定你要装的 RabbitMQ 版本反查它支持的 OTP 区间再从 Erlang 官方下载页选择对应的otp_win64_xx.x.exe。如果你对版本没偏好新项目直接上 RabbitMQ 3.12.x 或 3.13.x 配 OTP 26是目前最省心的组合如果是接已有系统版本要跟着服务端走别自作主张升级。1.3 怎么确认装完之后两者真的能配合装完别急着启服务先用两步确认。第一步命令行敲erl能进 Erlang shell 就说明 OTP 装好了输入erlang:system_info(otp_release).回车会返回一个主版本号字符串比如26这个数字要落在你选定的区间里。第二步进入 RabbitMQ 的sbin目录执行rabbitmqctl.bat status如果能正常输出节点名、版本、运行状态说明 RabbitMQ 已经能调用到 Erlang 并跟本机节点通上了。这两步都过了后面出问题的概率会小很多。2. Windows 下 Erlang 的安装路径与环境变量到底怎么摆2.1 安装包选择和安装目录Erlang 官网下载页会给出多个安装包Windows 上认准文件名里的win64和位数otp_win64_26.2.5.exe这种。安装过程本身没悬念一路下一步即可但安装路径值得停一下。默认会装到C:\Program Files\Erlang OTP或者带版本号的C:\Program Files\erl-26.2.5两种都可以用关键是后面环境变量要跟它一致。我的习惯是不要装到用户目录下的路径也不要装到带空格或者中文的目录里。原因很直接RabbitMQ 在 Windows 上有一批.bat脚本它们内部拼接路径时对空格的处理并不总是完美路径里出现空格偶尔会把参数切碎。Program Files自带一个空格官方脚本是能处理的但如果你自己改成“D:\我的软件\Erlang”那就纯属给自己找麻烦了。另外要记清楚一件事安装完成后Erlang 的 bin 目录长这样C:\Program Files\Erlang OTP\bin\里面能看到erl.exe、erlc.exe、epmd.exe。epmd这个进程后面会反复出现它是 Erlang 的端口映射守护进程负责节点之间的名字解析RabbitMQ 的心跳和集群通信都靠它。2.2 三个必须确认的环境变量环境变量这块网上教程给的名字五花八门实际上只要保证这三点就不会出问题。第一新建系统变量ERLANG_HOME值填 Erlang 的根目录注意不带末尾反斜杠比如C:\Program Files\Erlang OTP。这个名字不是官方强制的RabbitMQ 真正认的是后面两个但很多第三方脚本会读它加上没坏处。第二把%ERLANG_HOME%\bin追加到系统Path里。这一步决定了你在任意目录下能不能直接敲erl。第三确认系统里没有残留的旧 Erlang 路径。如果以前装过又没卸干净Path里可能还留着老的C:\Program Files\erl10.5\bin这种脏路径会让命令行调用到错误版本的erl.exe表现出来就是“明明装的是 OTP 26erl起来却是 24”。修改完环境变量务必开一个新的命令行窗口再验证。已经打开的 cmd 或者 PowerShell 不会重新读取系统变量这是新手最容易迷惑的地方之一变量明明改了敲erl还是提示找不到命令重启电脑才好——其实新开个窗口就行。2.3 验证 Erlang 能否被外部正常调用验证分三层一层比一层严格。第一层任意目录敲erl -version会打印版本信息。第二层进 Erlang shell直接敲erl执行erlang:system_info(otp_release).看主版本号。第三层在同一个窗口里敲epmd -names正常情况下如果当前没有 Erlang 节点在跑它会返回epmd: up and running on port 4369 with data:然后什么都不列或者提示没有节点。这说明 epmd 端口是通的。提示如果epmd -names报端口被占用或者直接连不上先别管 RabbitMQ先去解决 4369 端口的占用问题用netstat -ano | findstr 4369找到占用进程再决定是换端口还是结束进程。顺便说一个常被忽略的细节Windows 上 Erlang 会往%USERPROFILE%\.erlang.cookie写一个 cookie 文件同时服务模式下还会去读C:\Windows\System32\config\systemprofile\.erlang.cookie。这个 cookie 是节点间通信的“密钥”两个位置的文件内容必须一模一样。这是后面“unable to connect to node”这类报错的头号元凶先在这里埋个伏笔。3. RabbitMQ 的两种装法选错会多折腾两小时3.1 安装版 exe 和 zip 压缩版的取舍RabbitMQ 在 Windows 上有两条路。第一条是rabbitmq-server-3.13.x.exe这种安装版双击、下一步、勾选组件、完成它会自动帮你注册 Windows 服务省掉了手工安装服务的步骤适合纯粹的本地开发。第二条是 zip 压缩版解压出来一个目录里面sbin放着所有.bat脚本需要你自己执行rabbitmq-service.bat install注册服务和rabbitmq-service.bat start启动。我的建议是如果只是本地写代码调试安装版更省事如果是要部署到 Windows Server 上、或者需要精细控制数据目录和配置文件位置用 zip 版。zip 版的好处是所有东西都在一个目录里卸载就是删文件夹不会在系统里留下服务残留和注册表项——这一点在测试环境反复重装的时候特别香。不管哪种装法环境变量都要再补一个。新建RABBITMQ_HOME指向 RabbitMQ 解压目录安装版可以指向其安装目录然后把%RABBITMQ_HOME%\sbin加进Path。加这个是为了让你能在任意目录直接跑rabbitmqctl.bat、rabbitmq-plugins.bat、rabbitmq-diagnostics.bat而不用每次都 cd 到 sbin 里。3.2 以管理员身份注册服务这一步绝对不能省有个非常典型的失败场景用普通权限的 cmd 执行rabbitmq-service.bat install命令跑完了看起来没报错但services.msc里根本找不到 RabbitMQ 服务或者服务在但一启动就停。原因在于 Windows 服务注册需要写系统服务数据库普通用户没这个权限脚本在中间某一步静默失败了。正确姿势是开始菜单里找到“命令提示符”或者“Windows PowerShell”右键选择“以管理员身份运行”再 cd 到 sbin 目录执行注册和启动命令。顺序是rabbitmq-service.bat install然后再rabbitmq-service.bat start。启动完成后去services.msc里应该能看到名为RabbitMQ的服务启动类型一般是自动。服务注册时会有一个默认设置值得注意服务默认以LocalSystem账号运行。这就把我们前面说的 cookie 问题引出来了——LocalSystem的家目录是C:\Windows\System32\config\systemprofile它读的 cookie 在这个目录下而你用命令行执行rabbitmqctl.bat时是以你自己的账号身份运行的读的是C:\Users\你的用户名\.erlang.cookie。两边内容不一致就会报认证失败或者节点连不上。3.3 数据目录、日志目录和配置文件的位置Windows 下这几个路径新手特别容易找不到提前记住能省很多时间。日志默认在%APPDATA%\RabbitMQ\log\也就是C:\Users\你的用户名\AppData\Roaming\RabbitMQ\log\。如果服务是用LocalSystem跑的日志实际落在C:\Windows\System32\config\systemprofile\AppData\Roaming\RabbitMQ\log\。很多人找日志找半天找不到就是因为看错了账号对应的目录。数据目录默认在%APPDATA%\RabbitMQ\db\或者安装目录的db下消息持久化、队列元数据都在这。想迁移或者清理的时候动这个目录别乱删。配置文件rabbitmq.conf放在%APPDATA%\RabbitMQ\下也就是和 log、db 同级。这个文件默认不存在需要自己新建。新版本的配置语法是类 INI 的风格比如改端口就写listeners.tcp.default 5672比老版本那些 Erlang 元组格式友好太多。还有一个advanced.config只有在rabbitmq.conf覆盖不到的边缘场景才用得上日常基本不碰。4. 启动失败的排查链路从日志第一行往下看4.1 先看日志不要凭感觉猜服务启动失败第一件事是看services.msc里服务尝试启动后立刻停掉的提示然后直奔日志目录找.log文件。日志按时间命名最新的那个就是刚才这次启动的记录打开后从第一处error或crash开始读。比日志更快的办法是直接用rabbitmq-diagnostics.bat。在管理员命令行里执行rabbitmq-diagnostics.bat status它会尝试连本地节点如果连不上错误信息往往直接点明原因比如nodedown节点没起来、cookie相关提示认证失败、或者epmd相关错误。这是排查的起点比埋头翻日志高效得多。还有一条命令也值得记住rabbitmq-diagnostics.bat check_port_connectivity它会逐项检查各监听端口是否可用。如果 epmd 的 4369 或者 AMQP 的 5672 被别的软件占了这条命令会直接告诉你。4.2 cookie 不一致隐形杀手的完整处理流程我把这个坑单独拎出来讲因为它出现的频率最高而且报错信息不够直白。完整处理链路是这样第一步先找到当前用户目录下的 cookieC:\Users\你的用户名\.erlang.cookie。这个文件是隐藏文件需要开启“显示隐藏文件”或者在资源管理器地址栏直接敲完整路径也可以用type %USERPROFILE%\.erlang.cookie在命令行里打印内容。第二步找到服务账号对应的 cookieC:\Windows\System32\config\systemprofile\.erlang.cookie。同样用type打印内容。第三步比对两个文件内容。如果不一致把用户目录下的内容复制到 systemprofile 那个文件里覆盖掉。内容就是一个字符串注意别多加换行或者空格。搞完这一步用管理员命令行执行net stop RabbitMQ再net start RabbitMQ多数情况下服务就正常了。注意修改前先备份原 cookie 文件改错了还能还原。另外cookie 文件所在目录的权限要保证服务账号有读取权限systemprofile目录在某些系统上权限比较紧如果发现服务仍然读不到需要右键属性里的“安全”标签给SYSTEM主体确认读取权限。如果你嫌这种双 cookie 的机制烦也可以在注册服务时把服务登录账号改成你自己的用户账号这样两边的家目录就是同一个了cookie 自然一致。不过这么做的前提是你账号有“作为服务登录”的权限需要在本地安全策略里授予操作起来比改 cookie 更绕新手还是建议走复制 cookie 这条路。4.3 端口占用与 hostname 引发的节点名问题排完 cookie下一个高频原因是端口占用。RabbitMQ 相关的端口有这么几个4369 是 epmd5672 是 AMQP 协议15672 是管理界面25672 是节点间通信如果开了 MQTT 插件还有 1883 和 15675。任何一个被占服务都可能起不来或者起来之后功能不全。用netstat -ano | findstr 4369 5672 15672 25672可以一次性列出这些端口的占用情况拿到 PID 后用任务管理器看是哪个进程。常见的占用者是别的消息中间件、某些开发工具自带的嵌入式服务、以及本机之前没清干净的 RabbitMQ 实例。另一类问题出在主机名上。Erlang 节点名默认是rabbit你的计算机名。如果计算机名里带中文、带下划线、带空格或者计算机名改过但服务注册时记录的是旧名字节点名就会解析失败。验证方法是执行rabbitmqctl.bat status看它输出的节点名再对比hostname命令的输出。不一致就去服务注册信息里重新注册先rabbitmq-service.bat remove再install。如果确实没办法改计算机名可以在rabbitmq.conf里显式指定节点名或者设置环境变量RABBITMQ_NODENAME还有一种做法是设置RABBITMQ_USE_LONGNAMEtrue让它使用完整域名。这几个方案里显式指定节点名最稳妥。4.4 路径含空格、用户名含中文的连锁反应这一条比较隐晦但确实存在。前面提到的C:\Program Files路径里那个空格官方脚本是处理了的但如果用户名是中文也会出问题因为%USERPROFILE%展开出来是C:\Users\张三\这个中文路径会被拼进 cookie 路径、日志路径、数据路径里一部分老版本脚本对非 ASCII 路径的兼容并不好。排查方式很简单如果是新电脑、用户名是中文装之前就把用户目录下的 RabbitMQ 相关路径换成纯英文的。最省事的做法是在D:\rabbitmq这种纯英文目录下解压 zip 版然后在rabbitmq-env.conf里指定RABBITMQ_BASE指向这个目录把 log、db、cookie 全都挪过去。这个配置文件放在 RabbitMQ 安装目录的sbin下格式是简单的键值对很容易写。5. 管理界面打开与账号权限落地5.1 rabbitmq_management 插件的启用顺序服务起来了不代表能打开网页。管理界面是插件默认不启用。启用命令是rabbitmq-plugins.bat enable rabbitmq_management要在管理员命令行、且在 sbin 目录下执行。执行完它会输出几个插件的启用列表包括rabbitmq_management、rabbitmq_management_agent、rabbitmq_web_dispatch这几个依赖。这里有个顺序陷阱如果服务还没启动就执行启用插件命令命令可能会失败或者看起来成功了但实际没生效。正确顺序是先确保服务在运行再启用插件。启用之后保险起见重启一次服务然后浏览器访问http://localhost:15672。访问不到的时候按这个顺序排查先netstat -ano | findstr 15672确认端口在监听再看 Windows 防火墙有没有拦第一次启动时系统通常会弹窗询问是否允许如果当时点了“取消”后面就得手动去防火墙里加规则最后确认浏览器没走错地址比如把 http 写成了 https。5.2 用户、vhost、权限三件套guest账号默认存在密码也是guest但它有个硬限制只允许从本机localhost登录。这意味着你在同一台机器上用浏览器访问完全没问题但后端服务如果部署在另一台机器上、用 guest 去连是一定连不上的而且报错信息只是朴素的认证失败很容易让人困惑。所以只要有任何跨机器访问的需求第一件事就是新建用户。命令行操作如下# 新建用户密码自己定 rabbitmqctl.bat add_user myuser MyStrongPass123 # 设置角色administrator 是管理员monitoring 只能看 rabbitmqctl.bat set_user_tags myuser administrator # 新建一个虚拟主机 rabbitmqctl.bat add_vhost /myapp # 给用户授权三个点分别代表配置、写、读权限空字符串表示不限制 rabbitmqctl.bat set_permissions -p /myapp myuser .* .* .* # 删掉没必要保留的 guest或者只保留它做本地调试 rabbitmqctl.bat delete_user guest这套命令里set_permissions后面那三个正则参数是常见踩坑点。三个参数依次对应配置权限、写权限、读权限用.*表示全部允许。如果写成了三引号空串或者漏了参数用户创建成功了但连上之后发不出消息也收不到消息报权限相关的错。另外 vhost 这个概念要理解清楚它相当于一个逻辑隔离的命名空间交换机和队列都归属某个 vhost用户必须对目标 vhost 有权限才能操作。5.3 前端直连 RabbitMQ 的取舍热词里出现过“前端访问 rabbitmq”这里必须泼一盆冷水。RabbitMQ 的 AMQP 协议走的是 5672这是一个二进制协议浏览器里没法直接建连。所谓“前端访问”实际上有三种做法一是后端搭一层 WebSocket 或者 SSE把消息推给前端RabbitMQ 只跟后端打交道这是最常规也最安全的方案。二是用 RabbitMQ 的 Web-STOMP 或者 Web-MQTT 插件把协议包装成浏览器能用的形式走 15674 或 15675 端口但这两个插件在新版本里维护状态一般生产环境用得少。三是前端完全绕过后端用 STOMP over WebSocket 直连这种方案意味着连接凭证暴露在浏览器里权限控制做不干净就有安全风险除非是内网演示否则不建议。如果你确实要用 Web-STOMP启用命令是rabbitmq-plugins.bat enable rabbitmq_web_stomp然后在前端用 STOMP 客户端连ws://你的IP:15674/ws账号密码用前面创建的用户。别忘了 vhost 要在连接 URL 里带上路径是/ws这个端点不带 vhostvhost 通过 STOMP 帧里的host头指定这一点文档写得比较散第一次配容易漏。6. MQTT 插件接入与客户端联调6.1 开启 rabbitmq_mqtt 与端口规划RabbitMQ 内置了 MQTT 支持适合物联网这类设备端场景。启用命令是rabbitmq-plugins.bat enable rabbitmq_mqtt默认监听 1883。如果你还要在浏览器里用 MQTT over WebSocket再加一个rabbitmq_web_mqtt它默认监听 15675。启用完成后执行rabbitmq-diagnostics.bat listeners这条命令会列出当前所有监听端口确认 1883 在里面。如果不在八成是插件没启用成功再看一次启用命令的输出。有个细节值得记一笔MQTT 插件对客户端标识client id有长度限制早期版本限制在 23 个字符以内超了会被服务端断开报错信息也比较隐晦。如果你用的客户端自动生成的 client id 特别长连不上先怀疑这个。现在的版本限制放宽了很多但换客户端测试的时候留意一下没坏处。6.2 用 MQTTX 验证连通MQTTX 是个跨平台的 MQTT 客户端图形界面很直观。连的时候按这个填地址填服务器 IP本机就是 127.0.0.1端口 1883用户名和密码填前面创建的那个 RabbitMQ 用户client id 随便起个短一点的英文。连上之后订阅一个主题比如test/#然后自己往这个主题发一条消息能在订阅侧收到就说明链路通了。如果连不上按这个顺序查先确认 1883 端口在监听netstat -ano | findstr 1883再确认用户对目标 vhost 有权限因为 MQTT 插件映射主题时也需要 vhost 权限然后确认用户名密码没写错MQTT 握手阶段返回的错误码不太直白经常只给一个“连接被拒绝”。最后确认客户端的 MQTT 协议版本多数客户端默认走 3.1.1这个版本 RabbitMQ 支持得最稳。注意MQTT 的 topic 在 RabbitMQ 内部会映射成交换机上的路由键如果你的业务需要持久化消息要在 MQTT 连接参数里把 QoS 设成 1 或 2同时确保对应的交换机是持久化的。默认情况下 MQTT 插件会为每个 vhost 建一个amq.topic交换机别去手动删它。7. 几个我实际踩过、文档里不太写的坑最后聊几个散落的经验都是实际装机过程中遇到的不一定是“错误”但会让人卡很久。第一个Windows 上erl_crash.dump文件会出现在工作目录里。如果 RabbitMQ 因为 Erlang 层面崩溃过这个文件会生成在启动命令的当前目录下一般是C:\Windows\System32因为服务是以LocalSystem身份跑的。看到这个文件说明 Erlang 虚拟机崩了不是 RabbitMQ 逻辑错这时候去读文件头部的崩溃原因往往比 RabbitMQ 日志更有价值。第二个rabbitmqctl.bat每次执行都要先连节点如果节点没起来它会重试一段时间然后超时感觉像卡住。加了-n参数指定节点名可以少走弯路本地调试记住节点名是rabbit你的计算机名直接rabbitmqctl.bat -n rabbit你的计算机名 status就行。第三个重装 RabbitMQ 之前一定要先rabbitmq-service.bat stop再rabbitmq-service.bat remove把旧服务清掉。直接覆盖安装很容易出现“服务名冲突”“节点名重复”这类问题表现出来就是新装的服务起不来而系统里还挂着个幽灵服务。第四个别用taskkill去强杀节点进程。Erlang 节点被杀掉之后本地可能会残留一个epmd进程或者一个锁文件导致下次启动报节点已经在运行。如果实在杀不干净手动结束epmd.exe再重启服务或者重启电脑是最干脆的办法。第五个关于国内镜像。Erlang 官网下载速度有时候不太稳定可以找一些高校或云厂商提供的镜像站获取安装包但一定要核对文件哈希别装到被篡改的包。RabbitMQ 的安装包同理优先走官方或者可信渠道下载装完用rabbitmqctl.bat version核对一下版本号跟下载页写的是否一致这是我养成的习惯避免拿到旧版本还以为是新的。我个人在这套环境上折腾最多的时间不是安装本身而是每次换机器、换系统重来一遍时忘了把 OTP 和 RabbitMQ 的版本对应关系再对一次。把这张兼容表存进笔记里装之前花十秒核对比事后花两小时排查 nodedown 要划算得多。
返回列表