本文目录导读:

我来详细介绍PHP项目中使用RabbitMQ的方法。
安装RabbitMQ PHP客户端
使用Composer安装
composer require php-amqplib/php-amqplib
安装RabbitMQ服务(如果未安装)
# Ubuntu/Debian sudo apt-get install rabbitmq-server # CentOS/RHEL sudo yum install rabbitmq-server # 启动服务 sudo systemctl start rabbitmq-server sudo systemctl enable rabbitmq-server
基本使用示例
生产者(发送消息)
<?php
require_once 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class RabbitMQProducer {
private $connection;
private $channel;
private $exchange;
private $queue;
public function __construct($config = []) {
$defaultConfig = [
'host' => 'localhost',
'port' => 5672,
'user' => 'guest',
'password' => 'guest',
'vhost' => '/'
];
$config = array_merge($defaultConfig, $config);
try {
$this->connection = new AMQPStreamConnection(
$config['host'],
$config['port'],
$config['user'],
$config['password'],
$config['vhost']
);
$this->channel = $this->connection->channel();
} catch (\Exception $e) {
throw new \Exception("RabbitMQ连接失败: " . $e->getMessage());
}
}
public function sendMessage($queue, $message, $exchange = '') {
// 声明队列
$this->channel->queue_declare(
$queue, // 队列名
false, // passive
true, // durable(持久化)
false, // exclusive
false // auto_delete
);
// 创建消息
$msg = new AMQPMessage(
json_encode($message),
[
'content_type' => 'application/json',
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
]
);
// 发送消息
$this->channel->basic_publish(
$msg,
$exchange,
$queue
);
echo " [x] 发送消息: " . json_encode($message) . "\n";
}
public function __destruct() {
$this->channel->close();
$this->connection->close();
}
}
// 使用示例
$producer = new RabbitMQProducer();
$producer->sendMessage('task_queue', [
'id' => 1,
'type' => 'email',
'data' => [
'to' => 'user@example.com',
'subject' => 'Test Subject',
'body' => 'Hello World'
]
]);
消费者(接收消息)
<?php
require_once 'vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
class RabbitMQConsumer {
private $connection;
private $channel;
public function __construct($config = []) {
$defaultConfig = [
'host' => 'localhost',
'port' => 5672,
'user' => 'guest',
'password' => 'guest',
'vhost' => '/'
];
$config = array_merge($defaultConfig, $config);
try {
$this->connection = new AMQPStreamConnection(
$config['host'],
$config['port'],
$config['user'],
$config['password'],
$config['vhost']
);
$this->channel = $this->connection->channel();
} catch (\Exception $e) {
throw new \Exception("RabbitMQ连接失败: " . $e->getMessage());
}
}
public function consume($queue, $callback) {
// 声明队列
$this->channel->queue_declare(
$queue,
false,
true, // durable
false,
false
);
// 设置每次只取一条消息
$this->channel->basic_qos(
null, // prefetch_size
1, // prefetch_count
null // a_global
);
echo " [*] 等待消息,按Ctrl+C退出\n";
// 消费消息
$this->channel->basic_consume(
$queue,
'', // consumer_tag
false, // no_local
false, // no_ack
false, // exclusive
false, // nowait
function($msg) use ($callback) {
echo " [x] 收到消息: " . $msg->body . "\n";
// 处理消息
$data = json_decode($msg->body, true);
$result = $callback($data);
// 确认消息已处理
$msg->delivery_info['channel']->basic_ack(
$msg->delivery_info['delivery_tag']
);
}
);
// 循环等待消息
while ($this->channel->is_consuming()) {
$this->channel->wait();
}
}
public function __destruct() {
$this->channel->close();
$this->connection->close();
}
}
// 使用示例
$consumer = new RabbitMQConsumer();
$consumer->consume('task_queue', function($data) {
// 处理业务逻辑
echo "处理任务: " . $data['type'] . "\n";
// 模拟耗时任务
sleep(2);
echo "任务完成: " . $data['id'] . "\n";
return true;
});
高级用法
工作队列(任务分发)
// 生产者 - 分发任务
class TaskProducer {
public function sendTasks() {
$producer = new RabbitMQProducer();
for ($i = 0; $i < 10; $i++) {
$task = [
'id' => $i,
'type' => 'task',
'data' => "任务内容 $i",
'timestamp' => time()
];
$producer->sendMessage('task_queue', $task);
}
}
}
// 消费者 - 处理任务(可启动多个实例)
class TaskWorker {
public function start() {
$consumer = new RabbitMQConsumer();
$consumer->consume('task_queue', function($task) {
// 处理任务
echo "Worker " . getmypid() . " 处理任务: " . $task['id'] . "\n";
// 模拟处理时间
sleep(rand(1, 3));
return true;
});
}
}
发布/订阅模式
// 发布者
class Publisher {
public function publish($exchange, $message) {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
// 声明交换机
$channel->exchange_declare(
$exchange,
'fanout', // 类型:fanout, direct, topic, headers
false,
false,
false
);
$msg = new AMQPMessage(json_encode($message));
$channel->basic_publish($msg, $exchange);
echo " [x] 发布消息到交换机 $exchange\n";
$channel->close();
$connection->close();
}
}
// 订阅者
class Subscriber {
public function subscribe($exchange, $queueName = '') {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
// 声明交换机
$channel->exchange_declare(
$exchange,
'fanout',
false,
false,
false
);
// 创建临时队列
list($queueName, ,) = $channel->queue_declare(
$queueName,
false,
false,
true, // exclusive
false
);
// 绑定队列到交换机
$channel->queue_bind($queueName, $exchange);
echo " [*] 等待日志消息,按Ctrl+C退出\n";
$channel->basic_consume($queueName, '', false, true, false, false, function($msg) {
echo " [x] 收到: " . $msg->body . "\n";
});
while ($channel->is_consuming()) {
$channel->wait();
}
}
}
路由模式(Direct Exchange)
// 生产者
class DirectProducer {
public function send($routingKey, $message) {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->exchange_declare('direct_logs', 'direct', false, false, false);
$msg = new AMQPMessage(json_encode($message));
$channel->basic_publish($msg, 'direct_logs', $routingKey);
echo " [x] 发送 [$routingKey]: " . json_encode($message) . "\n";
$channel->close();
$connection->close();
}
}
// 消费者
class DirectConsumer {
public function consume($routingKeys) {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->exchange_declare('direct_logs', 'direct', false, false, false);
list($queueName, ,) = $channel->queue_declare("", false, false, true, false);
// 绑定多个路由键
foreach ($routingKeys as $routingKey) {
$channel->queue_bind($queueName, 'direct_logs', $routingKey);
}
echo " [*] 等待消息,按Ctrl+C退出\n";
$channel->basic_consume($queueName, '', false, true, false, false, function($msg) {
echo " [x] " . $msg->delivery_info['routing_key'] . ":" . $msg->body . "\n";
});
while ($channel->is_consuming()) {
$channel->wait();
}
}
}
配置文件和最佳实践
配置文件(config/rabbitmq.php)
<?php
return [
'host' => env('RABBITMQ_HOST', 'localhost'),
'port' => env('RABBITMQ_PORT', 5672),
'user' => env('RABBITMQ_USER', 'guest'),
'password' => env('RABBITMQ_PASSWORD', 'guest'),
'vhost' => env('RABBITMQ_VHOST', '/'),
'options' => [
'heartbeat' => 60,
'read_write_timeout' => 120,
],
'queues' => [
'task_queue' => [
'name' => 'task_queue',
'durable' => true,
],
'email_queue' => [
'name' => 'email_queue',
'durable' => true,
],
'notification_queue' => [
'name' => 'notification_queue',
'durable' => true,
],
],
'exchanges' => [
'logs' => [
'name' => 'logs',
'type' => 'fanout',
],
'direct_logs' => [
'name' => 'direct_logs',
'type' => 'direct',
],
],
];
连接池管理
<?php
class RabbitMQPool {
private static $instance = null;
private $connections = [];
private $config;
private function __construct($config) {
$this->config = $config;
}
public static function getInstance($config = []) {
if (self::$instance === null) {
self::$instance = new self($config);
}
return self::$instance;
}
public function getConnection() {
// 简单的连接复用
if (!empty($this->connections)) {
return array_pop($this->connections);
}
return new AMQPStreamConnection(
$this->config['host'],
$this->config['port'],
$this->config['user'],
$this->config['password']
);
}
public function releaseConnection($connection) {
$this->connections[] = $connection;
}
}
常见问题处理
连接失败处理
try {
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
} catch (\Exception $e) {
// 记录日志
error_log("RabbitMQ连接失败: " . $e->getMessage());
// 重试逻辑
$retryCount = 0;
$maxRetries = 3;
while ($retryCount < $maxRetries) {
try {
sleep(2);
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
break;
} catch (\Exception $e) {
$retryCount++;
if ($retryCount >= $maxRetries) {
throw new \Exception("RabbitMQ连接失败,已重试{$maxRetries}次");
}
}
}
}
消息确认和重试
// 消费者中使用手动确认
$channel->basic_consume($queue, '', false, false, false, false, function($msg) {
try {
// 处理消息
processMessage(json_decode($msg->body, true));
// 确认消息
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
} catch (\Exception $e) {
// 处理失败,拒绝消息并可选择重新入队
$msg->delivery_info['channel']->basic_nack(
$msg->delivery_info['delivery_tag'],
false,
true // requeue
);
}
});
这些示例涵盖了RabbitMQ在PHP项目中的基本使用和高级用法,根据你的具体需求选择合适的模式进行实现。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播