Skip to content

RabbitMQ 虚拟主机(Virtual Host)

概述

虚拟主机(Virtual Host,简称 Vhost)是 RabbitMQ 中实现逻辑隔离的核心机制。每个 Vhost 拥有独立的 Exchange、Queue、Binding 和用户权限,类似于 MySQL 的数据库或 MongoDB 的数据库。通过 Vhost,可以在同一个 RabbitMQ Broker 上实现多租户隔离、不同环境隔离和资源隔离。

虚拟主机的核心作用

mermaid
graph TB
    subgraph RabbitMQ Broker
        subgraph Vhost / (Default)
            E1[Exchange]
            Q1[Queue]
        end
        
        subgraph Vhost /production
            E2[Exchange]
            Q2[Queue]
        end
        
        subgraph Vhost /development
            E3[Exchange]
            Q3[Queue]
        end
        
        subgraph Vhost /staging
            E4[Exchange]
            Q4[Queue]
        end
    end
    
    Client1 -->|/ (Default)| V1
    Client2 -->|/production| V2
    Client3 -->|/development| V3
    Client4 -->|/staging| V4

虚拟主机的主要作用:

  • 逻辑隔离:不同 Vhost 之间的资源完全隔离
  • 多租户支持:为不同客户或部门提供独立环境
  • 环境隔离:分离开发、测试、生产环境
  • 权限控制:基于 Vhost 进行细粒度权限管理

核心知识点

1. Vhost 的基本概念

每个 RabbitMQ Broker 都有一个默认的 Vhost,名称为 /

mermaid
graph LR
    subgraph Vhost 结构
        U1[User 1] -->|/vhost1| C1[Connection 1]
        U2[User 2] -->|/vhost2| C2[Connection 2]
        
        C1 --> E1[Exchange 1]
        C1 --> Q1[Queue 1]
        C1 --> B1[Binding 1]
        
        C2 --> E2[Exchange 2]
        C2 --> Q2[Queue 2]
        C2 --> B2[Binding 2]
    end

Vhost 包含以下组件:

  • Exchanges:交换机
  • Queues:队列
  • Bindings:绑定规则
  • Users:用户权限

2. Vhost 的特性

特性说明
逻辑隔离每个 Vhost 独立运行,互不影响
资源隔离独立的内存、磁盘配额
权限控制独立的用户权限体系
命名空间交换机和队列名称在同一 Vhost 内唯一

3. Vhost 的使用场景

mermaid
graph TB
    A[Vhost 使用场景] --> B[多租户隔离]
    A --> C[环境隔离]
    A --> D[业务隔离]
    A --> E[服务隔离]
    
    B --> B1[不同客户]
    B --> B2[不同部门]
    
    C --> C1[开发环境]
    C --> C2[测试环境]
    C --> C3[生产环境]
    
    D --> D1[订单服务]
    D --> D2[用户服务]
    D --> D3[通知服务]
    
    E --> E1[核心业务]
    E --> E2[非核心业务]

4. Vhost 权限管理

mermaid
graph LR
    subgraph 权限配置
        A[管理员] -->|创建| U[User]
        A -->|创建| V[Vhost]
        A -->|授权| P[Permissions]
    end
    
    P -->|configure| Q1[声明权限]
    P -->|write| Q2[发布权限]
    P -->|read| Q3[消费权限]

权限类型:

  • configure:创建/删除交换机和队列
  • write:发布消息
  • read:消费消息

代码示例

Vhost 管理基础操作

php
<?php

require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;

class VhostManager
{
    private $connection;
    private $channel;
    
    public function __construct(array $config = [])
    {
        $this->connection = new AMQPStreamConnection(
            $config['host'] ?? 'localhost',
            $config['port'] ?? 5672,
            $config['user'] ?? 'guest',
            $config['password'] ?? 'guest',
            $config['vhost'] ?? '/'
        );
        
        $this->channel = $this->connection->channel();
    }
    
    public function getCurrentVhost(): string
    {
        return $this->connection->getVhost();
    }
    
    public function declareVhost(string $vhost): void
    {
        $this->channel->exchange_declare('rabbit_vhost_manager', 'direct', false, true, false);
        
        echo "Vhost info retrieved: {$this->getCurrentVhost()}\n";
    }
    
    public function listExchanges(): array
    {
        return $this->channel->exchange_list();
    }
    
    public function listQueues(): array
    {
        return $this->channel->queue_list();
    }
    
    public function listBindings(): array
    {
        return $this->channel->binding_list();
    }
    
    public function close(): void
    {
        $this->channel->close();
        $this->connection->close();
    }
}

$manager = new VhostManager();

echo "Current Vhost: " . $manager->getCurrentVhost() . "\n";

$manager->close();

多 Vhost 连接管理

php
<?php

use PhpAmqpLib\Connection\AMQPStreamConnection;

class MultiVhostConnectionManager
{
    private $connections = [];
    private $config;
    
    public function __construct(array $baseConfig = [])
    {
        $this->config = array_merge([
            'host' => 'localhost',
            'port' => 5672,
            'user' => 'guest',
            'password' => 'guest'
        ], $baseConfig);
    }
    
    public function getConnection(string $vhost): AMQPStreamConnection
    {
        if (!isset($this->connections[$vhost])) {
            $this->connections[$vhost] = new AMQPStreamConnection(
                $this->config['host'],
                $this->config['port'],
                $this->config['user'],
                $this->config['password'],
                $vhost
            );
        }
        
        return $this->connections[$vhost];
    }
    
    public function getProductionConnection(): AMQPStreamConnection
    {
        return $this->getConnection('/production');
    }
    
    public function getDevelopmentConnection(): AMQPStreamConnection
    {
        return $this->getConnection('/development');
    }
    
    public function getStagingConnection(): AMQPStreamConnection
    {
        return $this->getConnection('/staging');
    }
    
    public function closeAll(): void
    {
        foreach ($this->connections as $vhost => $connection) {
            try {
                $connection->close();
                echo "Closed connection to vhost: {$vhost}\n";
            } catch (Exception $e) {
                echo "Error closing vhost {$vhost}: {$e->getMessage()}\n";
            }
        }
        
        $this->connections = [];
    }
}

$manager = new MultiVhostConnectionManager([
    'host' => 'localhost',
    'user' => 'admin',
    'password' => 'admin123'
]);

$prodConnection = $manager->getProductionConnection();
$devConnection = $manager->getDevelopmentConnection();

echo "Connected to production and development vhosts\n";

$manager->closeAll();

Vhost 配置模板

php
<?php

class VhostConfiguration
{
    public static function getVhostConfig(string $environment): array
    {
        $configs = [
            'production' => [
                'name' => '/production',
                'description' => 'Production environment',
                'limits' => [
                    'max_connections' => 1000,
                    'max_queues' => 500,
                    'max_exchanges' => 200
                ]
            ],
            'staging' => [
                'name' => '/staging',
                'description' => 'Staging environment',
                'limits' => [
                    'max_connections' => 100,
                    'max_queues' => 100,
                    'max_exchanges' => 50
                ]
            ],
            'development' => [
                'name' => '/development',
                'description' => 'Development environment',
                'limits' => [
                    'max_connections' => 50,
                    'max_queues' => 50,
                    'max_exchanges' => 30
                ]
            ]
        ];
        
        return $configs[$environment] ?? $configs['development'];
    }
    
    public static function getAllVhosts(): array
    {
        return [
            '/' => 'Default vhost',
            '/production' => 'Production environment',
            '/staging' => 'Staging environment',
            '/development' => 'Development environment',
            '/test' => 'Test environment'
        ];
    }
}

多租户 Vhost 系统

php
<?php

class TenantVhostManager
{
    private $adminConnection;
    private $channel;
    private $vhostPrefix = 'tenant_';
    
    public function __construct(array $config = [])
    {
        $this->adminConnection = new AMQPStreamConnection(
            $config['host'] ?? 'localhost',
            $config['port'] => 5672,
            $config['admin_user'] ?? 'admin',
            $config['admin_password'] ?? 'admin',
            '/'
        );
        
        $this->channel = $this->adminConnection->channel();
    }
    
    public function createTenantVhost(string $tenantId): void
    {
        $vhostName = $this->vhostPrefix . $tenantId;
        
        echo "Creating vhost: {$vhostName}\n";
        
        echo "Vhost {$vhostName} created (requires management plugin for full operations)\n";
    }
    
    public function setupTenantResources(string $tenantId, array $resources): void
    {
        $vhostName = $this->vhostPrefix . $tenantId;
        
        $connection = new AMQPStreamConnection(
            'localhost',
            5672,
            'admin',
            'admin',
            $vhostName
        );
        
        $channel = $connection->channel();
        
        if (!empty($resources['exchanges'])) {
            foreach ($resources['exchanges'] as $exchange) {
                $channel->exchange_declare(
                    $exchange['name'],
                    $exchange['type'] ?? 'direct',
                    false,
                    $exchange['durable'] ?? true,
                    false
                );
                
                echo "Created exchange: {$exchange['name']} in vhost {$vhostName}\n";
            }
        }
        
        if (!empty($resources['queues'])) {
            foreach ($resources['queues'] as $queue) {
                $channel->queue_declare(
                    $queue['name'],
                    false,
                    $queue['durable'] ?? true,
                    false,
                    false
                );
                
                echo "Created queue: {$queue['name']} in vhost {$vhostName}\n";
            }
        }
        
        $channel->close();
        $connection->close();
    }
    
    public function deleteTenantVhost(string $tenantId): void
    {
        $vhostName = $this->vhostPrefix . $tenantId;
        
        echo "Deleting vhost: {$vhostName}\n";
        
        echo "Vhost {$vhostName} deleted (requires management plugin for full operations)\n";
    }
    
    public function getTenantVhostName(string $tenantId): string
    {
        return $this->vhostPrefix . $tenantId;
    }
    
    public function close(): void
    {
        $this->channel->close();
        $this->adminConnection->close();
    }
}

$tenantManager = new TenantVhostManager([
    'host' => 'localhost',
    'admin_user' => 'admin',
    'admin_password' => 'admin123'
]);

$tenantManager->createTenantVhost('customer_001');

$tenantManager->setupTenantResources('customer_001', [
    'exchanges' => [
        ['name' => 'orders', 'type' => 'topic', 'durable' => true],
        ['name' => 'notifications', 'type' => 'fanout', 'durable' => true]
    ],
    'queues' => [
        ['name' => 'orders_queue', 'durable' => true],
        ['name' => 'notifications_queue', 'durable' => true]
    ]
]);

$tenantManager->close();

环境隔离系统

php
<?php

class EnvironmentIsolator
{
    private $baseConfig;
    private $connections = [];
    
    public function __construct(array $baseConfig = [])
    {
        $this->baseConfig = $baseConfig;
    }
    
    public function getEnvironmentConnection(string $environment): AMQPStreamConnection
    {
        if (!isset($this->connections[$environment])) {
            $vhost = $this->getEnvironmentVhost($environment);
            
            $this->connections[$environment] = new AMQPStreamConnection(
                $this->baseConfig['host'],
                $this->baseConfig['port'],
                $this->baseConfig['user'],
                $this->baseConfig['password'],
                $vhost
            );
            
            echo "Connected to {$environment} environment (vhost: {$vhost})\n";
        }
        
        return $this->connections[$environment];
    }
    
    public function getEnvironmentVhost(string $environment): string
    {
        $vhosts = [
            'production' => '/production',
            'staging' => '/staging',
            'development' => '/development',
            'test' => '/test',
            'local' => '/'
        ];
        
        return $vhosts[$environment] ?? '/' . $environment;
    }
    
    public function setupEnvironment(string $environment, array $config): void
    {
        $connection = $this->getEnvironmentConnection($environment);
        $channel = $connection->channel();
        
        if (!empty($config['exchanges'])) {
            foreach ($config['exchanges'] as $exchange) {
                $channel->exchange_declare(
                    $exchange['name'],
                    $exchange['type'] ?? 'direct',
                    false,
                    $exchange['durable'] ?? true,
                    false
                );
            }
        }
        
        if (!empty($config['queues'])) {
            foreach ($config['queues'] as $queue) {
                $channel->queue_declare(
                    $queue['name'],
                    false,
                    $queue['durable'] ?? true,
                    false,
                    false
                );
            }
        }
        
        echo "Environment '{$environment}' setup completed\n";
    }
    
    public function closeAll(): void
    {
        foreach ($this->connections as $env => $connection) {
            try {
                $connection->close();
                echo "Closed connection to {$env}\n";
            } catch (Exception $e) {
                echo "Error closing {$env}: {$e->getMessage()}\n";
            }
        }
        
        $this->connections = [];
    }
}

$isolator = new EnvironmentIsolator([
    'host' => 'localhost',
    'port' => 5672,
    'user' => 'admin',
    'password' => 'admin123'
]);

$isolator->setupEnvironment('development', [
    'exchanges' => [
        ['name' => 'events', 'type' => 'topic']
    ],
    'queues' => [
        ['name' => 'events_queue']
    ]
]);

$isolator->setupEnvironment('production', [
    'exchanges' => [
        ['name' => 'events', 'type' => 'topic']
    ],
    'queues' => [
        ['name' => 'events_queue'],
        ['name' => 'events_dlq']
    ]
]);

$prodConnection = $isolator->getEnvironmentConnection('production');

$isolator->closeAll();

实际应用场景

1. 多租户 SaaS 平台

php
<?php

class SaaSVhostManager
{
    private $manager;
    
    public function __construct()
    {
        $this->manager = new TenantVhostManager([
            'host' => 'localhost',
            'admin_user' => 'admin',
            'admin_password' => 'admin'
        ]);
    }
    
    public function provisionTenant(string $tenantId, string $plan): void
    {
        $vhostName = $this->manager->getTenantVhostName($tenantId);
        
        $resources = $this->getPlanResources($plan);
        
        $this->manager->createTenantVhost($tenantId);
        $this->manager->setupTenantResources($tenantId, $resources);
        
        echo "Tenant {$tenantId} provisioned with {$plan} plan\n";
    }
    
    public function upgradeTenant(string $tenantId, string $newPlan): void
    {
        $resources = $this->getPlanResources($newPlan);
        
        $this->manager->setupTenantResources($tenantId, $resources);
        
        echo "Tenant {$tenantId} upgraded to {$newPlan} plan\n";
    }
    
    public function deprovisionTenant(string $tenantId): void
    {
        $this->manager->deleteTenantVhost($tenantId);
        
        echo "Tenant {$tenantId} deprovisioned\n";
    }
    
    private function getPlanResources(string $plan): array
    {
        $plans = [
            'free' => [
                'exchanges' => [['name' => 'main', 'type' => 'direct']],
                'queues' => [['name' => 'default']]
            ],
            'basic' => [
                'exchanges' => [
                    ['name' => 'main', 'type' => 'direct'],
                    ['name' => 'events', 'type' => 'topic']
                ],
                'queues' => [
                    ['name' => 'default'],
                    ['name' => 'events']
                ]
            ],
            'enterprise' => [
                'exchanges' => [
                    ['name' => 'main', 'type' => 'direct'],
                    ['name' => 'events', 'type' => 'topic'],
                    ['name' => 'notifications', 'type' => 'fanout']
                ],
                'queues' => [
                    ['name' => 'default'],
                    ['name' => 'events'],
                    ['name' => 'notifications'],
                    ['name' => 'dlq']
                ]
            ]
        ];
        
        return $plans[$plan] ?? $plans['free'];
    }
}

$s SaaS = new SaaSVhostManager();

$s SaaS->provisionTenant('company_a', 'basic');
$s SaaS->provisionTenant('company_b', 'enterprise');

$s SaaS->upgradeTenant('company_a', 'enterprise');

2. 微服务隔离架构

php
<?php

class MicroserviceVhostManager
{
    private $connections = [];
    
    public function __construct(array $config = [])
    {
        $this->config = $config;
    }
    
    public function getServiceVhost(string $serviceName): string
    {
        return '/' . $serviceName;
    }
    
    public function connectToService(string $serviceName): AMQPStreamConnection
    {
        $key = 'service_' . $serviceName;
        
        if (!isset($this->connections[$key])) {
            $vhost = $this->getServiceVhost($serviceName);
            
            $this->connections[$key] = new AMQPStreamConnection(
                $this->config['host'],
                $this->config['port'],
                $this->config['user'],
                $this->config['password'],
                $vhost
            );
        }
        
        return $this->connections[$key];
    }
    
    public function setupServiceInfrastructure(string $serviceName, array $config): void
    {
        $connection = $this->connectToService($serviceName);
        $channel = $connection->channel();
        
        if (!empty($config['publishes'])) {
            foreach ($config['publishes'] as $exchange) {
                $channel->exchange_declare(
                    $exchange['name'],
                    $exchange['type'],
                    false,
                    true,
                    false
                );
            }
        }
        
        if (!empty($config['subscribes'])) {
            foreach ($config['subscribes'] as $queue) {
                $channel->queue_declare($queue['name'], false, true, false, false);
                
                if (!empty($queue['bindings'])) {
                    foreach ($queue['bindings'] as $binding) {
                        $channel->queue_bind(
                            $queue['name'],
                            $binding['exchange'],
                            $binding['routing_key'] ?? ''
                        );
                    }
                }
            }
        }
        
        echo "Service '{$serviceName}' infrastructure setup completed\n";
    }
    
    public function closeAll(): void
    {
        foreach ($this->connections as $key => $connection) {
            $connection->close();
        }
        $this->connections = [];
    }
}

$manager = new MicroserviceVhostManager([
    'host' => 'localhost',
    'port' => 5672,
    'user' => 'admin',
    'password' => 'admin123'
]);

$manager->setupServiceInfrastructure('orders', [
    'publishes' => [
        ['name' => 'order_events', 'type' => 'topic']
    ],
    'subscribes' => [
        ['name' => 'order_commands', 'bindings' => [
            ['exchange' => 'order_events', 'routing_key' => 'order.#']
        ]]
    ]
]);

$manager->setupServiceInfrastructure('notifications', [
    'publishes' => [
        ['name' => 'notification_events', 'type' => 'fanout']
    ],
    'subscribes' => [
        ['name' => 'email_queue', 'bindings' => [
            ['exchange' => 'notification_events']
        ]],
        ['name' => 'sms_queue', 'bindings' => [
            ['exchange' => 'notification_events']
        ]]
    ]
]);

$manager->closeAll();

3. 开发测试环境隔离

php
<?php

class DevTestIsolation
{
    private $manager;
    
    public function __construct()
    {
        $this->manager = new EnvironmentIsolator([
            'host' => 'localhost',
            'port' => 5672,
            'user' => 'developer',
            'password' => 'dev123'
        ]);
    }
    
    public function setupTestEnvironment(): void
    {
        $this->manager->setupEnvironment('test', [
            'exchanges' => [
                ['name' => 'test_events', 'type' => 'topic']
            ],
            'queues' => [
                ['name' => 'test_events_queue'],
                ['name' => 'test_events_dlq']
            ]
        ]);
        
        echo "Test environment setup completed\n";
    }
    
    public function runTest(string $testName, callable $test): void
    {
        $testConnection = $this->manager->getEnvironmentConnection('test');
        
        $channel = $testConnection->channel();
        
        $test($channel);
        
        echo "Test '{$testName}' completed\n";
    }
    
    public function cleanupTestEnvironment(): void
    {
        $testConnection = $this->manager->getEnvironmentConnection('test');
        $channel = $testConnection->channel();
        
        try {
            $channel->queue_delete('test_events_queue');
            $channel->queue_delete('test_events_dlq');
            $channel->exchange_delete('test_events');
            
            echo "Test environment cleaned up\n";
        } catch (Exception $e) {
            echo "Cleanup warning: {$e->getMessage()}\n";
        }
    }
}

$isolation = new DevTestIsolation();

$isolation->setupTestEnvironment();

$isolation->runTest('publish_message', function ($channel) {
    $message = new AMQPMessage('test message');
    $channel->basic_publish($message, 'test_events', 'test.key');
    
    echo "Test message published\n";
});

$isolation->runTest('consume_message', function ($channel) {
    $message = $channel->basic_get('test_events_queue');
    
    if ($message) {
        echo "Received: {$message->body}\n";
        $channel->basic_ack($message->getDeliveryTag());
    }
});

$isolation->cleanupTestEnvironment();

常见问题与解决方案

1. Vhost 不存在

问题原因

  • Vhost 未创建
  • Vhost 名称错误
  • 权限不足

解决方案

php
<?php

class VhostSafeConnector
{
    private $allowedVhosts = ['/', '/production', '/staging', '/development'];
    
    public function connect(string $vhost, array $config): ?AMQPStreamConnection
    {
        if (!in_array($vhost, $this->allowedVhosts)) {
            throw new InvalidArgumentException("Vhost '{$vhost}' is not allowed");
        }
        
        try {
            return new AMQPStreamConnection(
                $config['host'],
                $config['port'],
                $config['user'],
                $config['password'],
                $vhost
            );
        } catch (Exception $e) {
            if (strpos($e->getMessage(), 'ACCESS_REFUSED') !== false) {
                throw new RuntimeException("Access denied to vhost '{$vhost}'");
            }
            
            if (strpos($e->getMessage(), 'NOT_FOUND') !== false) {
                throw new RuntimeException("Vhost '{$vhost}' does not exist");
            }
            
            throw $e;
        }
    }
}

2. Vhost 资源耗尽

问题原因

  • 连接数达到上限
  • 队列数量达到上限
  • 内存限制

解决方案

php
<?php

class VhostResourceMonitor
{
    private $apiUrl;
    private $credentials;
    
    public function __construct(string $host, string $user, string $password)
    {
        $this->apiUrl = "http://{$host}:15672/api";
        $this->credentials = base64_encode("{$user}:{$password}");
    }
    
    public function getVhostOverview(string $vhost): array
    {
        $url = "{$this->apiUrl}/vhosts/" . urlencode($vhost);
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Authorization: Basic {$this->credentials}"
        ]);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return json_decode($response, true);
    }
    
    public function checkVhostHealth(string $vhost): array
    {
        $overview = $this->getVhostOverview($vhost);
        
        if (isset($overview['error'])) {
            return [
                'status' => 'error',
                'message' => $overview['error']
            ];
        }
        
        $status = 'healthy';
        $issues = [];
        
        if (($overview['messages'] ?? 0) > 100000) {
            $status = 'warning';
            $issues[] = 'High message backlog';
        }
        
        if (($overview['connections'] ?? 0) > 100) {
            $status = 'warning';
            $issues[] = 'High connection count';
        }
        
        return [
            'status' => $status,
            'vhost' => $vhost,
            'messages' => $overview['messages'] ?? 0,
            'connections' => $overview['connections'] ?? 0,
            'queues' => $overview['queues'] ?? 0,
            'issues' => $issues
        ];
    }
}

3. 跨 Vhost 通信问题

问题原因

  • Vhost 之间完全隔离
  • 无法直接跨 Vhost 路由

解决方案

php
<?php

class CrossVhostBridge
{
    private $connections = [];
    
    public function __construct(array $config = [])
    {
        $this->config = $config;
    }
    
    public function bridgeVhosts(string $sourceVhost, string $targetVhost, string $exchange, string $queue): void
    {
        $sourceConn = $this->getConnection($sourceVhost);
        $targetConn = $this->getConnection($targetVhost);
        
        $sourceChannel = $sourceConn->channel();
        $targetChannel = $targetConn->channel();
        
        $targetChannel->queue_declare($queue, false, true, false, false);
        
        $sourceChannel->basic_consume(
            $exchange,
            '',
            false,
            true,
            false,
            false,
            function ($message) use ($targetChannel, $queue) {
                $targetChannel->basic_publish(
                    $message,
                    '',
                    $queue
                );
            }
        );
        
        echo "Bridge created: {$sourceVhost} -> {$targetVhost}\n";
    }
    
    private function getConnection(string $vhost): AMQPStreamConnection
    {
        if (!isset($this->connections[$vhost])) {
            $this->connections[$vhost] = new AMQPStreamConnection(
                $this->config['host'],
                $this->config['port'],
                $this->config['user'],
                $this->config['password'],
                $vhost
            );
        }
        
        return $this->connections[$vhost];
    }
}

最佳实践建议

1. Vhost 命名规范

php
<?php

class VhostNamingConvention
{
    public static function forTenant(string $tenantId): string
    {
        return '/tenant_' . $tenantId;
    }
    
    public static function forEnvironment(string $environment): string
    {
        return '/' . $environment;
    }
    
    public static function forService(string $serviceName): string
    {
        return '/service_' . $serviceName;
    }
    
    public static function isValidVhostName(string $name): bool
    {
        return preg_match('/^\/[a-zA-Z0-9_/-]+$/', $name) === 1;
    }
}

2. Vhost 权限配置

php
<?php

class VhostPermissionTemplate
{
    public static function getAdminPermissions(): array
    {
        return [
            'configure' => '.*',
            'write' => '.*',
            'read' => '.*'
        ];
    }
    
    public static function getProducerPermissions(): array
    {
        return [
            'configure' => '^$',
            'write' => '^exchange\..+',
            'read' => '^$'
        ];
    }
    
    public static function getConsumerPermissions(): array
    {
        return [
            'configure' => '^$',
            'write' => '^$',
            'read' => '^queue\..+'
        ];
    }
}

3. Vhost 监控和告警

php
<?php

class VhostHealthChecker
{
    private $monitor;
    
    public function __construct(string $host, string $user, string $password)
    {
        $this->monitor = new VhostResourceMonitor($host, $user, $password);
    }
    
    public function checkAllVhosts(array $vhosts): array
    {
        $results = [];
        
        foreach ($vhosts as $vhost) {
            $results[$vhost] = $this->monitor->checkVhostHealth($vhost);
        }
        
        return $results;
    }
    
    public function checkAndAlert(array $vhosts, array $alertThresholds): void
    {
        $results = $this->checkAllVhosts($vhosts);
        
        foreach ($results as $vhost => $result) {
            if ($result['status'] === 'error') {
                $this->sendAlert("Vhost {$vhost} is inaccessible");
            }
            
            if ($result['status'] === 'warning') {
                $this->sendAlert("Vhost {$vhost} has issues: " . implode(', ', $result['issues']));
            }
        }
    }
    
    private function sendAlert(string $message): void
    {
        echo "ALERT: {$message}\n";
    }
}

相关链接