Skip to content

RabbitMQ 端口配置

概述

RabbitMQ 使用多个端口提供不同的服务,包括客户端连接、管理界面、集群通信、EPMD 等。正确配置端口对于 RabbitMQ 的正常运行和网络安全至关重要。本文档详细介绍 RabbitMQ 各端口的作用及配置方法。

核心知识点

端口总览

端口协议服务说明
5672TCPAMQP主要客户端连接端口
5671TCPAMQPSAMQP over SSL/TLS 加密连接
15672TCPManagementWeb 管理界面和 HTTP API
15671TCPManagement (SSL)管理界面 SSL 加密端口
25672TCPInter-node集群节点间通信端口
4369TCPEPMDErlang 端口映射守护进程
61613TCPSTOMPSTOMP 协议端口(需插件)
61614TCPSTOMPSSTOMP over SSL(需插件)
1883TCPMQTTMQTT 协议端口(需插件)
8883TCPMQTTSMQTT over SSL(需插件)
15674TCPWeb STOMPWebSocket STOMP(需插件)
15675TCPWeb MQTTWebSocket MQTT(需插件)

端口分类详解

RabbitMQ 端口架构
├── 客户端服务端口
│   ├── 5672   AMQP 标准端口
│   ├── 5671   AMQP SSL 端口
│   ├── 61613  STOMP 端口
│   ├── 61614  STOMP SSL 端口
│   ├── 1883   MQTT 端口
│   └── 8883   MQTT SSL 端口
├── 管理端口
│   ├── 15672  Management HTTP
│   ├── 15671  Management HTTPS
│   ├── 15674  Web STOMP
│   └── 15675  Web MQTT
└── 集群端口
    ├── 4369   EPMD
    └── 25672  Inter-node

端口范围说明

  • 固定端口:核心服务使用固定端口
  • 动态端口:RabbitMQ 可配置使用动态端口范围
  • EPMD 端口:Erlang 节点发现服务,固定为 4369

配置示例

rabbitmq.conf 端口配置

ini
# ========================================
# AMQP 端口配置
# ========================================

# AMQP 标准端口
# 默认值:5672
listeners.tcp.default = 5672

# 监听特定 IP
# listeners.tcp.default = 192.168.1.100:5672

# 监听多个端口
listeners.tcp.1 = 5672
listeners.tcp.2 = 5673

# 监听多个 IP
listeners.tcp.1 = 0.0.0.0:5672
listeners.tcp.2 = 127.0.0.1:5673

# ========================================
# AMQP SSL 端口配置
# ========================================

# AMQP over SSL 端口
listeners.ssl.default = 5671

# SSL 证书配置
ssl_options.cacertfile = /etc/rabbitmq/ssl/ca.pem
ssl_options.certfile = /etc/rabbitmq/ssl/server.pem
ssl_options.keyfile = /etc/rabbitmq/ssl/server.key
ssl_options.verify = verify_peer
ssl_options.fail_if_no_peer_cert = false

# ========================================
# 管理界面端口配置
# ========================================

# Management HTTP 端口
# 默认值:15672
management.tcp.port = 15672
management.tcp.ip = 0.0.0.0

# Management HTTPS 端口
management.ssl.port = 15671
management.ssl.ip = 0.0.0.0
management.ssl.cacertfile = /etc/rabbitmq/ssl/ca.pem
management.ssl.certfile = /etc/rabbitmq/ssl/server.pem
management.ssl.keyfile = /etc/rabbitmq/ssl/server.key

# ========================================
# 集群端口配置
# ========================================

# 集群节点间通信端口
# 默认值:RABBITMQ_NODE_PORT + 20000 = 25672
distribution.listener.port_range.min = 25672
distribution.listener.port_range.max = 25672

# EPMD 端口(通常不需要修改)
# erlang 分布式端口映射

# ========================================
# STOMP 协议端口(需启用插件)
# ========================================

# stomp.listeners.tcp.default = 61613
# stomp.listeners.ssl.default = 61614

# ========================================
# MQTT 协议端口(需启用插件)
# ========================================

# mqtt.listeners.tcp.default = 1883
# mqtt.listeners.ssl.default = 8883

# ========================================
# WebSocket 端口(需启用插件)
# ========================================

# web_stomp.tcp.port = 15674
# web_mqtt.tcp.port = 15675

advanced.config 高级端口配置

erlang
[
  {rabbit, [
    %% TCP 监听器配置
    {tcp_listeners, [5672]},
    
    %% SSL 监听器配置
    {ssl_listeners, [5671]},
    
    %% TCP 选项
    {tcp_listen_options, [
      {backlog, 4096},
      {nodelay, true},
      {linger, {true, 0}},
      {exit_on_close, false},
      {send_timeout, 15000},
      {send_timeout_close, true}
    ]},
    
    %% 集群端口范围
    {distribution_listener_port_range, {25672, 25672}}
  ]},
  
  {rabbitmq_mqtt, [
    %% MQTT 监听器
    {tcp_listeners, [1883]},
    {ssl_listeners, [8883]}
  ]},
  
  {rabbitmq_stomp, [
    %% STOMP 监听器
    {tcp_listeners, [61613]},
    {ssl_listeners, [61614]}
  ]}
].

Docker 端口映射配置

yaml
# docker-compose.yml
version: '3.8'

services:
  rabbitmq:
    image: rabbitmq:3.12-management
    container_name: rabbitmq
    ports:
      # AMQP 端口
      - "5672:5672"
      
      # AMQP SSL 端口
      - "5671:5671"
      
      # 管理界面
      - "15672:15672"
      
      # 管理界面 SSL
      - "15671:15671"
      
      # 集群通信(多节点时需要)
      - "25672:25672"
      
      # EPMD(集群发现)
      - "4369:4369"
      
      # MQTT(可选)
      # - "1883:1883"
      # - "8883:8883"
      
      # STOMP(可选)
      # - "61613:61613"
      
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=admin123
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    restart: unless-stopped

volumes:
  rabbitmq_data:

PHP 代码示例

端口检测工具

php
<?php

class RabbitMQPortChecker
{
    private string $host;
    private array $ports = [
        'amqp' => 5672,
        'amqps' => 5671,
        'management' => 15672,
        'management_ssl' => 15671,
        'inter_node' => 25672,
        'epmd' => 4369,
        'mqtt' => 1883,
        'mqtts' => 8883,
        'stomp' => 61613,
        'stomps' => 61614,
    ];

    public function __construct(string $host = 'localhost')
    {
        $this->host = $host;
    }

    public function checkPort(string $name, int $port, int $timeout = 2): array
    {
        $starttime = microtime(true);
        $socket = @fsockopen($this->host, $port, $errno, $errstr, $timeout);
        $endtime = microtime(true);

        if ($socket) {
            fclose($socket);
            return [
                'name' => $name,
                'port' => $port,
                'status' => 'open',
                'response_time' => round(($endtime - $starttime) * 1000, 2) . 'ms',
            ];
        }

        return [
            'name' => $name,
            'port' => $port,
            'status' => 'closed',
            'error' => $errstr,
        ];
    }

    public function checkAllPorts(): array
    {
        $results = [];
        foreach ($this->ports as $name => $port) {
            $results[$name] = $this->checkPort($name, $port);
        }
        return $results;
    }

    public function printReport(): void
    {
        echo "RabbitMQ 端口检测报告\n";
        echo "主机: {$this->host}\n";
        echo str_repeat("=", 60) . "\n";
        echo sprintf("%-20s %-10s %-10s %s\n", '服务名称', '端口', '状态', '响应时间');
        echo str_repeat("-", 60) . "\n";

        $results = $this->checkAllPorts();
        foreach ($results as $result) {
            $status = $result['status'] === 'open' ? '✅ 开放' : '❌ 关闭';
            $responseTime = $result['status'] === 'open' ? $result['response_time'] : '-';
            echo sprintf("%-20s %-10d %-10s %s\n", 
                $result['name'], 
                $result['port'], 
                $status, 
                $responseTime
            );
        }
    }
}

// 使用示例
$checker = new RabbitMQPortChecker('localhost');
$checker->printReport();

通过 API 获取端口信息

php
<?php

class RabbitMQPortManager
{
    private string $host;
    private int $apiPort;
    private string $username;
    private string $password;

    public function __construct(
        string $host = 'localhost',
        int $apiPort = 15672,
        string $username = 'guest',
        string $password = 'guest'
    ) {
        $this->host = $host;
        $this->apiPort = $apiPort;
        $this->username = $username;
        $this->password = $password;
    }

    private function request(string $endpoint): array
    {
        $url = "http://{$this->host}:{$this->apiPort}/api/{$endpoint}";
        
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_USERPWD => "{$this->username}:{$this->password}",
            CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        return [
            'status' => $httpCode,
            'data' => json_decode($response, true)
        ];
    }

    public function getListeners(): array
    {
        $response = $this->request('listeners');
        
        if ($response['status'] !== 200) {
            return [];
        }

        return array_map(function ($listener) {
            return [
                'node' => $listener['node'] ?? 'unknown',
                'protocol' => $listener['protocol'] ?? 'unknown',
                'ip_address' => $listener['ip_address'] ?? '0.0.0.0',
                'port' => $listener['port'] ?? 0,
            ];
        }, $response['data'] ?? []);
    }

    public function printListeners(): void
    {
        $listeners = $this->getListeners();
        
        echo "RabbitMQ 监听端口列表\n";
        echo str_repeat("=", 60) . "\n";
        echo sprintf("%-20s %-10s %-15s %s\n", '协议', '端口', 'IP 地址', '节点');
        echo str_repeat("-", 60) . "\n";
        
        foreach ($listeners as $listener) {
            echo sprintf("%-20s %-10d %-15s %s\n",
                $listener['protocol'],
                $listener['port'],
                $listener['ip_address'],
                $listener['node']
            );
        }
    }

    public function getPortStatistics(): array
    {
        $overview = $this->request('overview');
        $nodes = $this->request('nodes');
        
        $stats = [
            'amqp_connections' => $overview['data']['object_totals']['connections'] ?? 0,
            'channels' => $overview['data']['object_totals']['channels'] ?? 0,
        ];

        if (!empty($nodes['data'])) {
            $node = $nodes['data'][0];
            $stats['node_port'] = $node['node_port'] ?? 5672;
            $stats['management_port'] = $this->apiPort;
        }

        return $stats;
    }
}

// 使用示例
$manager = new RabbitMQPortManager('localhost', 15672, 'admin', 'password');
$manager->printListeners();

防火墙配置生成器

php
<?php

class RabbitMQFirewallGenerator
{
    private array $requiredPorts = [];

    public function addPort(string $name, int $port, string $protocol = 'tcp'): self
    {
        $this->requiredPorts[] = [
            'name' => $name,
            'port' => $port,
            'protocol' => $protocol,
        ];
        return $this;
    }

    public function addStandardPorts(): self
    {
        $this->addPort('AMQP', 5672);
        $this->addPort('AMQPS', 5671);
        $this->addPort('Management', 15672);
        $this->addPort('Management SSL', 15671);
        return $this;
    }

    public function addClusterPorts(): self
    {
        $this->addPort('Inter-node', 25672);
        $this->addPort('EPMD', 4369);
        return $this;
    }

    public function addMQTTPorts(): self
    {
        $this->addPort('MQTT', 1883);
        $this->addPort('MQTTS', 8883);
        return $this;
    }

    public function generateIPTables(): string
    {
        $rules = [];
        $rules[] = "# RabbitMQ IPTables 防火墙规则";
        $rules[] = "# 生成时间: " . date('Y-m-d H:i:s');
        $rules[] = "";

        foreach ($this->requiredPorts as $port) {
            $rules[] = sprintf(
                "iptables -A INPUT -p %s --dport %d -m comment --comment \"RabbitMQ %s\" -j ACCEPT",
                $port['protocol'],
                $port['port'],
                $port['name']
            );
        }

        return implode("\n", $rules);
    }

    public function generateFirewalld(): string
    {
        $rules = [];
        $rules[] = "# RabbitMQ Firewalld 防火墙规则";
        $rules[] = "# 生成时间: " . date('Y-m-d H:i:s');
        $rules[] = "";

        foreach ($this->requiredPorts as $port) {
            $rules[] = sprintf(
                "firewall-cmd --permanent --add-port=%d/%s",
                $port['port'],
                $port['protocol']
            );
        }
        
        $rules[] = "";
        $rules[] = "firewall-cmd --reload";

        return implode("\n", $rules);
    }

    public function generateUFW(): string
    {
        $rules = [];
        $rules[] = "# RabbitMQ UFW 防火墙规则";
        $rules[] = "# 生成时间: " . date('Y-m-d H:i:s');
        $rules[] = "";

        foreach ($this->requiredPorts as $port) {
            $rules[] = sprintf(
                "ufw allow %d/%s comment 'RabbitMQ %s'",
                $port['port'],
                $port['protocol'],
                $port['name']
            );
        }

        return implode("\n", $rules);
    }
}

// 使用示例
$generator = new RabbitMQFirewallGenerator();
$generator->addStandardPorts()
          ->addClusterPorts();

echo "=== IPTables 规则 ===\n";
echo $generator->generateIPTables();
echo "\n\n=== Firewalld 规则 ===\n";
echo $generator->generateFirewalld();
echo "\n\n=== UFW 规则 ===\n";
echo $generator->generateUFW();

实际应用场景

场景一:单机开发环境

ini
# 开发环境端口配置
# 只开放必要的端口

# AMQP 客户端连接
listeners.tcp.default = 5672

# 管理界面(仅本地访问)
management.tcp.port = 15672
management.tcp.ip = 127.0.0.1

# 不需要集群端口

场景二:生产环境标准配置

ini
# 生产环境端口配置

# AMQP 标准端口(内网)
listeners.tcp.default = 10.0.0.10:5672

# AMQP SSL 端口(公网)
listeners.ssl.default = 0.0.0.0:5671

# 管理界面(仅内网)
management.tcp.port = 15672
management.tcp.ip = 10.0.0.10

# 集群通信端口
distribution.listener.port_range.min = 25672
distribution.listener.port_range.max = 25672

场景三:多协议支持

ini
# 多协议端口配置

# AMQP
listeners.tcp.default = 5672
listeners.ssl.default = 5671

# MQTT(需启用 rabbitmq_mqtt 插件)
mqtt.listeners.tcp.default = 1883
mqtt.listeners.ssl.default = 8883

# STOMP(需启用 rabbitmq_stomp 插件)
stomp.listeners.tcp.default = 61613
stomp.listeners.ssl.default = 61614

# WebSocket(需启用相应插件)
web_stomp.tcp.port = 15674
web_mqtt.tcp.port = 15675

常见问题与解决方案

问题一:端口被占用

原因分析

  • 其他服务已占用端口
  • RabbitMQ 未正确关闭

解决方案

bash
# 查看端口占用情况
netstat -tlnp | grep 5672
# 或
lsof -i :5672
# 或
ss -tlnp | grep 5672

# 查找并终止占用进程
kill -9 $(lsof -t -i:5672)

# 修改 RabbitMQ 端口
# 在 rabbitmq.conf 中设置
listeners.tcp.default = 5673

问题二:防火墙阻止连接

原因分析

  • 防火墙未开放端口
  • 安全组规则限制

解决方案

bash
# CentOS/RHEL (firewalld)
firewall-cmd --permanent --add-port=5672/tcp
firewall-cmd --permanent --add-port=15672/tcp
firewall-cmd --reload

# Ubuntu (ufw)
ufw allow 5672/tcp
ufw allow 15672/tcp

# 直接使用 iptables
iptables -A INPUT -p tcp --dport 5672 -j ACCEPT
iptables -A INPUT -p tcp --dport 15672 -j ACCEPT
service iptables save

# 验证规则
iptables -L -n | grep 5672

问题三:集群节点无法通信

原因分析

  • EPMD 端口未开放
  • Inter-node 端口未开放
  • 节点间网络不通

解决方案

bash
# 开放集群必要端口
# EPMD 端口
firewall-cmd --permanent --add-port=4369/tcp

# Inter-node 端口(默认为 NODE_PORT + 20000)
firewall-cmd --permanent --add-port=25672/tcp
firewall-cmd --reload

# 测试端口连通性
telnet node2.example.com 4369
telnet node2.example.com 25672

# 检查 EPMD 服务
epmd -names

问题四:管理界面无法访问

原因分析

  • 管理插件未启用
  • 端口绑定到 127.0.0.1
  • 防火墙阻止

解决方案

bash
# 启用管理插件
rabbitmq-plugins enable rabbitmq_management

# 检查端口绑定
netstat -tlnp | grep 15672

# 修改绑定 IP
# rabbitmq.conf
management.tcp.ip = 0.0.0.0

# 重启服务
systemctl restart rabbitmq-server

最佳实践建议

1. 端口安全配置

ini
# 安全配置建议

# AMQP 仅绑定内网 IP
listeners.tcp.default = 10.0.0.10:5672

# 公网访问使用 SSL
listeners.ssl.default = 0.0.0.0:5671

# 管理界面仅内网访问
management.tcp.ip = 10.0.0.10

# 或使用反向代理
# management.tcp.ip = 127.0.0.1

2. 端口监控配置

bash
#!/bin/bash
# port-monitor.sh

PORTS="5672 15672 25672 4369"
ALERT_EMAIL="admin@example.com"

for port in $PORTS; do
    if ! nc -z localhost $port 2>/dev/null; then
        echo "Alert: RabbitMQ port $port is not responding!" | \
        mail -s "RabbitMQ Port Alert" $ALERT_EMAIL
    fi
done

3. Docker 网络配置

yaml
# 推荐的 Docker 网络配置
version: '3.8'

networks:
  rabbitmq_net:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16

services:
  rabbitmq:
    image: rabbitmq:3.12-management
    networks:
      rabbitmq_net:
        ipv4_address: 172.28.0.10
    ports:
      # 仅暴露必要端口
      - "5672:5672"
      - "15672:15672"
    # 集群端口仅在内部网络使用

4. 端口文档化

bash
# /etc/rabbitmq/ports.conf
# RabbitMQ 端口配置说明

# 客户端端口
AMQP_PORT=5672
AMQPS_PORT=5671

# 管理端口
MGMT_PORT=15672
MGMT_SSL_PORT=15671

# 集群端口
EPMD_PORT=4369
INTERNODE_PORT=25672

# 协议端口(可选)
MQTT_PORT=1883
STOMP_PORT=61613

相关链接