PHP使用rabbitMQ

在 PHP 中使用 RabbitMQ 通常是为了处理异步任务、队列、消息推送等场景,特别是在高并发、分布式系统中,RabbitMQ 提供了可靠的消息队列服务。RabbitMQ 是基于 AMQP 协议的消息中间件,具有高效、可靠、可扩展的特点。

下面将介绍如何在 PHP 中使用 RabbitMQ,并结合场景给出实现方法。

一、RabbitMQ 基础概念

  1. Producer(生产者):发送消息的客户端,负责将消息发送到消息队列。
  2. Consumer(消费者):接收消息的客户端,从队列中获取消息并处理。
  3. Queue(队列):存储消息的中间容器,生产者将消息发送到队列,消费者从队列中取出消息处理。
  4. Exchange(交换机):接收生产者发来的消息,并根据路由规则分发到队列。
  5. Binding(绑定):将队列绑定到交换机,使得消息能够根据规则路由到对应的队列。

二、安装和配置 RabbitMQ

  1. 安装 RabbitMQ 服务器 你可以通过包管理工具(如 apt-getyum)来安装 RabbitMQ,也可以在官方提供的 Docker 镜像上运行 RabbitMQ 服务器:

    bash 复制代码
    docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management
  2. 管理 RabbitMQ RabbitMQ 提供了一个管理插件,可以通过 Web UI 进行管理。访问 http://localhost:15672,默认账号密码都是 guest

  3. 安装 PHP 客户端库 使用 php-amqplib 来连接 RabbitMQ。在项目中可以通过 Composer 安装:

    bash 复制代码
    composer require php-amqplib/php-amqplib

三、PHP 使用 RabbitMQ 实例

1. 生产者发送消息
php 复制代码
<?php
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

// 创建连接到 RabbitMQ 服务器
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

// 声明队列
$channel->queue_declare('task_queue', false, true, false, false);

// 发送的消息内容
$data = "Hello World!";
$msg = new AMQPMessage($data, array('delivery_mode' => 2)); // 设置消息为持久化

// 发布消息到队列
$channel->basic_publish($msg, '', 'task_queue');

echo " [x] Sent 'Hello World!'\n";

// 关闭连接
$channel->close();
$connection->close();
?>

解释:

  • queue_declare 用于声明队列。如果队列不存在,则会创建。如果队列已经存在,则不会做任何操作。
  • basic_publish 用于将消息发布到队列中。
  • 使用 delivery_mode 设置消息持久化(2 表示持久化)。
2. 消费者接收消息
php 复制代码
<?php
require_once __DIR__ . '/vendor/autoload.php';

use PhpAmqpLib\Connection\AMQPStreamConnection;

// 创建连接到 RabbitMQ 服务器
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();

// 声明队列
$channel->queue_declare('task_queue', false, true, false, false);

echo " [*] Waiting for messages. To exit press CTRL+C\n";

// 回调函数,用于处理接收到的消息
$callback = function ($msg) {
    echo ' [x] Received ', $msg->body, "\n";
    // 模拟任务处理
    sleep(substr_count($msg->body, '.')); 
    echo " [x] Done\n";
    // 手动确认消息已经处理
    $msg->ack();
};

// 告诉 RabbitMQ 在同一时间不要发送多于一条消息给一个消费者
$channel->basic_qos(null, 1, null);

// 告诉 RabbitMQ 使用回调函数来接收消息,并手动确认消息
$channel->basic_consume('task_queue', '', false, false, false, false, $callback);

// 等待消息进入队列
while ($channel->is_consuming()) {
    $channel->wait();
}

// 关闭连接
$channel->close();
$connection->close();
?>

解释:

  • 消费者通过 basic_consume 来订阅队列的消息,并指定一个回调函数 callback 来处理收到的消息。
  • basic_qos(null, 1, null) 是为了设置"公平分发",确保在消费者处理完前一条消息后才会接收到下一条消息。
  • msg->ack() 是用来手动确认消息已经处理完毕,RabbitMQ 才会将该消息从队列中删除。
3. RabbitMQ 工作队列的应用场景
  • 异步任务处理:比如发送邮件、生成报告、图片处理等,客户端将任务发送到消息队列,消费者异步处理任务。
  • 负载均衡:多个消费者监听同一个队列,RabbitMQ 会将消息均匀分发到每个消费者上,实现任务的负载均衡。
  • 任务重试 :结合 acknack 确认机制,如果消费者在处理消息时出现错误,可以拒绝该消息并重新入队列处理。

四、RabbitMQ 高级特性

1. 消息持久化

消息持久化是为了防止 RabbitMQ 崩溃或重启时消息丢失。要做到持久化,需要将队列和消息都设置为持久化。

  • 持久化队列 :在声明队列时,设置 durable 参数为 true
  • 持久化消息 :在创建消息时,设置 delivery_mode 参数为 2
2. 延迟队列(延时任务)

通过 RabbitMQ 的 x-delayed-message 插件,可以实现延时任务。消息发送后不会立即被消费,而是经过一段时间后才会被放入队列中消费。

3. 消息确认机制

消息确认机制是为了确保消息被正确处理,避免消息丢失。RabbitMQ 提供了手动和自动两种消息确认方式。手动确认(如上述消费者中的 ack)可以确保消息在处理失败时不会丢失。

五、总结

RabbitMQ 是一个强大且灵活的消息队列系统,结合 PHP 可以实现很多高级应用场景,如异步任务、任务重试、负载均衡等。在高并发和分布式系统中,RabbitMQ 可以有效提高系统的可扩展性和稳定性。

相关推荐
2401_857439696 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
来一杯龙舌兰10 小时前
【RabbitMQ】RabbitMQ保证消息不丢失的N种策略的思想总结
分布式·rabbitmq·ruby·持久化·ack·消息确认
Smile灬凉城66613 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
奥顺15 小时前
PHPUnit使用指南:编写高效的单元测试
大数据·mysql·开源·php
黑客Jack16 小时前
网络安全加密
安全·web安全·php
龙哥·三年风水19 小时前
workman服务端开发模式-应用开发-后端api推送修改二
分布式·gateway·php
Allen Bright20 小时前
Spring Boot 整合 RabbitMQ:从入门到实践
spring boot·rabbitmq·java-rabbitmq
计算机徐师兄20 小时前
基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
小程序·php·家具购物小程序·家具购物微信小程序·家具购物
希雅不是希望21 小时前
Ubuntu命令行网络配置
网络·ubuntu·php
龙哥·三年风水1 天前
workman服务端开发模式-应用开发-后端api推送修改一
分布式·gateway·php