
在Linux服务器上装RabbitMQ看起来就是把几个rpm包装上去的事但真正落地的时候一坑连一坑Erlang版本对不上、启动报错、网页打不开、guest用户登录被拒、MQTT连不上。我把最近在几台不同Linux发行版上装RabbitMQ的过程完整梳理了一遍把能踩的坑都踩完了从在线安装、离线安装到Docker Compose部署再到管理界面、用户权限和MQTT插件配置一条条说清楚。这篇适合刚接触RabbitMQ的运维和开发也适合在内网环境里被迫手动装包的朋友照着一步步做基本不会再被安装问题卡住。1. 动手之前先把版本和安装方式想明白1.1 Erlang和RabbitMQ的版本配对是第一步RabbitMQ是基于Erlang/OTP写的所以它对Erlang的版本有严格要求和依赖。很多安装失败、启动报错、节点起不来的问题根子上全是Erlang版本不匹配。这一点在官方文档里有张兼容性对照表但说句实话没几个人愿意去翻所以我直接给结论。我自己常用的配对关系是这样的RabbitMQ版本Erlang版本范围适用场景3.13.x26.2 ~ 27.x新项目首选支持最新特性3.12.x25.3 ~ 26.1稳健生产环境常见3.11.x24.2 ~ 25.2老项目维护较多3.8.x21.3 ~ 23.0老旧环境非必要不碰这里要特别注意一点Erlang版本不是越新越好。你装了Erlang 27然后去配RabbitMQ 3.12启动的时候大概率报一个类似Failed to start erlang node的错原因就是版本不在支持范围内。所以在安装之前先确定你要装哪个RabbitMQ版本再反推Erlang版本这个顺序千万别搞反。另外不同Linux发行版的Erlang包管理结果差异很大。CentOS/OpenEuler/Alibaba Cloud Linux自带的erlang仓库版本往往偏旧有些甚至只有R21或R22而RabbitMQ新版本根本跑不起来。所以我不建议直接用系统自带的erlang包最好从RabbitMQ官方维护的Erlang仓库装或者直接用官方的rpm包后面第2节会详细说。1.2 三种安装方式怎么选RabbitMQ在Linux上常见的安装方式我归纳为三种在线安装、离线安装、Docker Compose部署。很多人上来就问“哪个方式最好”但这个问题没有标准答案取决于你的实际环境。在线安装适合能访问外网的机器操作最简单yum install几个命令搞定依赖关系系统自动处理。缺点是国内访问官方源偶尔慢需要配镜像源而且如果团队内有多台机器要装每台都得重复走一遍网络流程。离线安装适合内网环境、涉密网络、以及没有外网的虚拟机。操作麻烦一点你得先在能联网的机器上下载好所有rpm包和依赖包再拷到目标机器上。好处是一旦准备好装起来反而很快而且可控。热搜里有人问“如何在内网的欧拉系统安装rabbitmq”说的就是这种场景。Docker Compose部署适合不想污染宿主机环境的人尤其是开发测试环境。一条docker compose up就能起来升级、回滚都方便。缺点是对容器化和镜像源有一定要求而且性能上比裸装略有一点损耗。我个人的建议是生产环境用裸装开发和测试环境用Docker Compose内网用离线包。1.3 不同Linux发行版的坑先打个预防针Linux发行版太多了但RabbitMQ的安装大体分两派一类是CentOS/RHEL系包括Alibaba Cloud Linux 3、OpenEuler、Rocky Linux等用yum/dnf管理包一类是Debian/Ubuntu系用apt管理包。我这台机器是Alibaba Cloud Linux 3本质上跟CentOS 8完全兼容所以直接用el8的rpm包就行。OpenEuler 22.03 LTS也是RHEL系同样能套用el8的包但有少数依赖会有出入建议先把epel源配上。Ubuntu 20.04/22.04则是用cloudsmith源或直接下载deb包操作思路一样命令不同。如果你在装的过程中发现yum报No matching packages之类的问题八成是系统版本识别和仓库不匹配别急着换包先用cat /etc/os-release看清楚系统版本再决定用el7还是el8还是el9的包。2. 在线安装完整实操CentOS/RHEL系2.1 准备基础环境和依赖在线安装的前提是机器能联网并且yum源正常工作。先做三件事更新系统时间、安装基础工具、关闭SELinux或者放行相关端口。# 更新软件包索引 yum makecache # 安装基础工具 yum install -y epel-release socat logrotate wget # 查看系统版本 cat /etc/os-releaseepel-release很关键因为RabbitMQ的rpm包依赖socat而socat在默认源里经常找不到必须靠EPEL源补上。如果你用的是OpenEuler或者Alibaba Cloud Linux 3可能已经内置了socat但为了保险还是装一下。SELinux方面我建议先把状态搞清楚不要一上来就关getenforce如果输出是Enforcing你可以选择临时改成Permissive测试或者一步到位改成disabled。生产环境如果要开SELinux需要额外配置SELinux策略比较折腾。我自己的习惯是先Permissive跑通后续再专门处理安全策略不然排查问题的时候经常会多出一堆莫名其妙的Permission denied。2.2 安装指定版本的Erlang这里我强烈建议直接用RabbitMQ团队维护的Erlang不要用系统的erlang包。RabbitMQ官方提供了一个单独的yum仓库专门用来发布与RabbitMQ版本匹配的Erlang版本。先导入GPG keyrpm --import https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc然后添加Erlang的yum源。以el8为例在/etc/yum.repos.d/rabbitmq-erlang.repo里写入[rabbitmq-erlang] namerabbitmq-erlang baseurlhttps://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/rpm/el/8/$basearch enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://dl.cloudsmith.io/public/rabbitmq/rabbitmq-erlang/gpg.KEY如果你用的是el7或el9把baseurl里的el/8改成对应版本就行。接下来直接安装yum install -y erlang装完验证一下版本erl -version正常情况下会输出类似Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 14.x这样的信息。注意如果版本太新比如27.x你后续装RabbitMQ之前一定要确认支持范围之前我用Erlang 27去配RabbitMQ 3.12启动直接报错最后老老实实降回26.2才跑通。2.3 安装RabbitMQ并启动RabbitMQ自身也提供了一个yum源。同样在/etc/yum.repos.d/rabbitmq-server.repo里写[rabbitmq-server] namerabbitmq-server baseurlhttps://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/rpm/el/8/$basearch enabled1 gpgcheck1 repo_gpgcheck1 gpgkeyhttps://dl.cloudsmith.io/public/rabbitmq/rabbitmq-server/gpg.KEY然后安装yum install -y rabbitmq-server安装完成后先设置主机名解析。这一步很多教程都没提但非常重要。RabbitMQ节点的启动依赖主机名解析如果/etc/hosts里没有本机主机名的映射会出现节点无法启动或者启动后节点名异常的问题。# 查看当前主机名 hostname # 编辑/etc/hosts把主机名映射到本机IP echo 127.0.0.1 $(hostname) /etc/hosts然后启动并设置开机自启systemctl start rabbitmq-server systemctl enable rabbitmq-server systemctl status rabbitmq-server看到active (running)就说明起来了。这时候默认的guest用户是能用的但guest只能在localhost访问远程是连不上的所以下一步就要配管理界面和用户。3. Web管理界面的开启与用户权限分配3.1 启用rabbitmq_management插件RabbitMQ装好之后默认是不带Web管理界面的需要手动启用管理插件。这也是热搜里很多人在问“rabbitmq服务器网页如何看和管理”的原因。rabbitmq-plugins enable rabbitmq_management执行后会输出一系列插件启用成功的信息。然后重启RabbitMQ让插件完全加载systemctl restart rabbitmq-server管理界面默认跑在15672端口浏览器访问http://服务器IP:15672就能看到登录页。这里要注意几个点RabbitMQ监听的几个默认端口要记清楚5672是AMQP协议端口15672是Web管理界面端口1883是MQTT协议端口如果启用25672是集群内部通信端口。防火墙如果开着这些端口都要放行firewall-cmd --permanent --add-port15672/tcp firewall-cmd --permanent --add-port5672/tcp firewall-cmd --permanent --add-port1883/tcp firewall-cmd --reload我用的是firewalld如果是iptables或者云安全组操作方式不同但思路一样别把这个忘了。很多时候RabbitMQ本身一点问题没有网页就是打不开查一圈发现是防火墙没放行。3.2 创建管理员和业务用户RabbitMQ默认的guest用户只允许从localhost登录这是配置文件里写死的安全策略。所以远程访问时必须自己创建用户。我一般会创建两个维度一个管理员用户用来登录Web管理界面一个业务用户给应用程序连。# 创建管理员用户 rabbitmqctl add_user admin Admin123456 rabbitmqctl set_user_tags admin administrator rabbitmqctl set_permissions -p / admin .* .* .* # 创建业务用户假设应用名是app1 rabbitmqctl add_user app1 App123456 rabbitmqctl set_user_tags app1 monitoring rabbitmqctl set_permissions -p / app1 ^app1-.* .* .*我来解释一下每条命令在干什么。add_user就是加用户后面跟用户名和密码。set_user_tags是打标签administrator标签意味着这个用户有管理员的全部权限monitoring标签只能看监控数据适合给应用用。set_permissions是配置vhost下的权限三个.*分别对应配置权限、写权限、读权限。业务用户的权限我不建议直接给全如果你的应用是队列生产者只需要写权限和读权限配置权限可以收紧。比如rabbitmqctl set_permissions -p / app1 ^app1-.* .* .*第一个参数是队列/交换机资源的正则匹配^app1-.*表示app1只能操作名字以app1-开头的资源这样可以有效隔离不同业务之间的队列防止互相干扰。3.3 权限模型快速理解RabbitMQ的权限模型是三个维度的vhost、资源名、操作类型。vhost类似于数据库里的库每个vhost之间是隔离的。RabbitMQ默认有个/vhost大多数场景都直接用它但如果团队多业务线同时用建议按业务建vhost权限也能分得更干净。创建vhost的命令如下rabbitmqctl add_vhost /dev rabbitmqctl set_permissions -p /dev app1 .* .* .*操作类型上configure对应声明队列、交换机、绑定关系write对应发消息、绑定队列read对应消费消息、清除队列。理解了这个模型你才能在分配权限的时候做到心里有数而不是照着别人的命令一通瞎敲。4. 开启MQTT插件并用MQTTX实测连接4.1 启用MQTT插件RabbitMQ原生支持MQTT协议通过插件的方式提供。这个功能很实用因为很多物联网设备、小程序、移动端推送都是走MQTT而非AMQP而RabbitMQ可以作为统一的接入层把MQTT消息转发到AMQP队列也可以用AMQP的exchange来路由MQTT消息。开启方式rabbitmq-plugins enable rabbitmq_mqtt systemctl restart rabbitmq-server验证插件是否启用rabbitmq-plugins list | grep mqtt看到[E*] rabbitmq_mqtt说明已启用。默认MQTT监听1883端口WebSocket的MQTT监听15675端口。如果你的Web端需要用MQTT over WebSocket用15675不是1883这个很容易搞混。4.2 MQTTX连接测试MQTTX是我用得比较顺手的MQTT测试客户端支持Windows、Mac、Linux也有Web版。打开MQTTX新建连接配置如下配置项值Namelocal-testHostmqtt://服务器IP:1883Usernameapp1PasswordApp123456注意Host那里要写mqtt://前缀不是tcp://也不是ws://。如果用WebSocket则是ws://服务器IP:15675/mqtt路径最后要带/mqtt少了这个后缀连不上。连接起来之后再新建一个订阅主题比如test/topic然后往这个主题发一条消息能收到就说明整个链路通了。如果连接失败大概率是三个原因端口没放行、用户权限不对、或者插件没启用。实际测试中我还发现一个坑如果用了guest账号去连MQTT即使开了远程访问配置MQTT插件默认也不会拒绝guest但为了安全不建议这么干。用刚才创建的业务用户app1最稳妥。5. Docker Compose方式部署推荐5.1 写一个能直接用的compose文件前面对裸装方式说了很多但在你的开发环境、测试环境我还是更推荐用Docker Compose。原因是快、干净、可复现。配置一个docker-compose.yml以后任何机器上一条命令就能起同样的环境。services: rabbitmq: image: rabbitmq:3.13-management container_name: rabbitmq hostname: my-rabbit restart: always environment: TZ: Asia/Shanghai RABBITMQ_DEFAULT_USER: admin RABBITMQ_DEFAULT_PASS: Admin123456 ports: - 5672:5672 - 15672:15672 - 1883:1883 - 15675:15675 volumes: - ./rabbitmq_data:/var/lib/rabbitmq - ./rabbitmq_log:/var/log/rabbitmq重点说两个细节。第一个是hostname: my-rabbit这个必须显式设置因为RabbitMQ的节点名是由hostname决定的如果容器不固定hostname每次重建容器节点名都会变这会给后续的集群配置和持久化带来额外麻烦。第二个是image: rabbitmq:3.13-management这个镜像已经内置了Web管理插件不用再enable。但MQTT插件不在里面需要在容器启动后手动启用docker exec -it rabbitmq rabbitmq-plugins enable rabbitmq_mqtt如果你希望一启动就带MQTT插件建议自己打一个镜像Dockerfile里加一行RUN rabbitmq-plugins enable rabbitmq_mqtt即可。启动命令docker compose up -d启动后可以用docker compose logs -f看日志看到Server startup complete就说明起好了。5.2 数据持久化与配置挂载上面的compose文件已经把RabbitMQ的数据目录和日志目录挂载出来了分别映射到宿主机的./rabbitmq_data和./rabbitmq_log。这个设计是为了防止容器销毁后数据丢失。RabbitMQ的元数据队列、交换机、用户、权限等都存在/var/lib/rabbitmq下如果不挂载容器一删所有配置全部归零这是个生产事故级别的问题。如果你想自定义RabbitMQ配置比如修改内存阈值、开启延迟队列插件可以再挂一个配置文件volumes: - ./rabbitmq.conf:/etc/rabbitmq/rabbitmq.confrabbitmq.conf的格式是key-value形式比如loopback_users.guest false vm_memory_high_watermark.relative 0.6第一行是允许guest远程登录第二行是设置内存高水位线为物理内存的60%。这些配置在Docker环境下尤其有用因为容器内存限制和宿主机内存不一致默认配置有时会误判。6. 常见问题与排查6.1 启动失败的集中排查不管在线装还是离线装启动失败是碰到最多的一个问题。这里我把常见的原因和排查思路整理成一张表方便大家对照现象可能原因排查步骤systemctl start超时或报错Erlang版本不匹配erl -version查看版本对照兼容表日志提示nodename错误主机名未加入 /etc/hostsecho 127.0.0.1 $(hostname) /etc/hosts报Address already in use5672端口被占用ss -lntp | grep 5672找到占用进程报epmd error for host/etc/hosts解析问题或epmd未启动epmd -names查看节点注册情况日志里有memory limit字样系统可用内存过小调整RabbitMQ内存水位配置或增加内存日志文件的默认位置是/var/log/rabbitmq/启动失败后第一步永远是去翻日志不是反复systemctl start。日志里往往已经把原因说得很明白了。6.2 网页打不开的检查步骤管理界面打不开很多人第一反应是RabbitMQ出问题了但实际排查下来多半是网络和端口的问题。我的排查顺序是这样的第一确认管理插件已经启用rabbitmq-plugins list | grep management看到[E*] rabbitmq_management才是启用的。第二确认服务监听状态ss -lntp | grep 15672看到LISTEN说明监听正常。第三确认防火墙和云安全组curl http://127.0.0.1:15672能通而外网不能通基本就是防火墙/安全组的问题。第四确认浏览器访问的是管理端口而不是5672端口。5672是AMQP协议端口用浏览器访问当然打不开。如果以上都正常还是打不开看下RabbitMQ是否在容器里运行。容器里要确认端口映射有没有写对docker compose ps能直接看到端口映射状态。6.3 内网/离线环境怎么装内网环境不能访问外部yum源这时候最靠谱的方式是把所有需要的rpm包在能联网的机器上先下载好再用yum localinstall安装。具体步骤是# 在能联网的机器上下载Erlang和RabbitMQ及其依赖 yum install --downloadonly --downloaddir/tmp/rabbitmq-rpm erlang rabbitmq-server socat logrotate # 将/tmp/rabbitmq-rpm目录整个拷贝到内网机器 # 在内网机器上安装 cd /tmp/rabbitmq-rpm yum localinstall -y *.rpm这里要注意yum install --downloadonly只下载不安装但前提是当前机器已经能解析并下载这些包。如果你在外网的机器上没有安装RabbitMQ直接--downloadonly可能还是会把依赖关系解析出来这个没问题它能下载所有需要的rpm包。还要注意一点不同Linux发行版的内核和依赖库版本不同最好在相同发行版上下载、相同发行版上安装跨发行版拷包经常出现glibc版本冲突。比如你在CentOS 9上下载的包别拿到OpenEuler 20.03上装大概率会有依赖问题。6.4 进程起来了但连接被拒绝RabbitMQ进程是running状态但客户端连接5672被拒绝这个情况也不少。特别要注意的是RabbitMQ监听5672默认绑定在所有网卡上但如果你自定义过NODE_IP_ADDRESS环境变量它就会只监听指定IP。排查方法ss -lntp | grep 5672如果看到监听地址是127.0.0.1:5672那说明RabbitMQ被配置为仅本机访问。检查/etc/rabbitmq/rabbitmq.conf是否有类似listeners.tcp.local 127.0.0.1:5672有的话改成0.0.0.0:5672或直接删掉然后重启。另一个常见问题是客户端连接时用的vhost不存在。比如你配置了业务用户只对/dev这个vhost有权限但客户端连接时vhost填的是/连接也会报错。客户端里的vhost参数一定要和权限配置里的一致。我个人的习惯是先把裸装方式完整跑通一遍理解每一步在做什么然后再在测试环境用Docker Compose简化部署。因为只有理解了底层逻辑遇到问题才知道去哪里排查。如果一上来就直接抄compose文件出了问题反而更懵。最后分享一个小技巧RabbitMQ的rabbitmq-diagnostics命令是排查问题的一个很好用的工具。比如rabbitmq-diagnostics ping可以快速确认节点是否存活rabbitmq-diagnostics -q listeners能看到所有端口监听状态rabbitmq-diagnostics -q alarms能看到节点是否有告警。遇到问题先跑这三个命令比盲猜高效得多。