一.rabbitMQ原理
生产者产生信息交给交换机,交换机再通过建立通道绑定队列,把消息存到队列里面,消费者再通过建立通道从队列里拿到消息进行处理。
二.基于Laravel8简单封装rabbitMQ模型示例
**
* 消息队列封装模型类
*/
namespace App\Models;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class Queue
{
// 连接MQ
private static function linkMq(){
$config = config('queue.connections.rabbitmq')['hosts'][0];
return new AMQPStreamConnection($config['host'], $config['port'], $config['user'], $config['password'], $config['vhost']);
}
// 生产者生产
public function productionMq($queue,$exchange,$messageBody){
$conn = self::linkMq();
if($conn->isConnected()) {
// 创建通道
$pass = $conn->channel();
// 声明一个队列
$pass->queue_declare($queue, false, true, false, false);
// 声明一个交换机
$pass->exchange_declare($exchange, 'direct', false, true, false);
// 队列和交换器绑定
$pass->queue_bind($queue, $exchange);
// 开启确认通道(这里开启ack机制 推送消息成功/失败可以对其处理)
$pass->confirm_select();
// 消息需要组装
$message = new AMQPMessage($messageBody, array('content_type' => 'text/plain', 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
// 推送消息
$pass->basic_publish($message, $exchange);
// 推送成功
$pass->set_ack_handler(function(AMQPMessage $message){
echo $message->body."推送成功";
});
// 推送失败
$pass->set_nack_handler(function(AMQPMessage $message){
echo $message->body."推送失败";
});
// 等待服务器上的挂起的ACK和NACK
$pass->wait_for_pending_acks();
// 通道关闭
$pass->close();
// 链接关闭
$conn->close();
}else{
echo '链接失败';
}
}
// 消费者消费
public function consumer($queue,$callback){
$conn = self::linkMq();
if($conn->isConnected()) {
// 创建通道
$pass = $conn->channel();
//取出消息
$message = $pass->basic_get($queue);
// 回调
if(!empty($message)) {
$res = $callback($message->body);
if ($res) { //成功
// 确认消息被消费
$pass->basic_ack($message->getDeliveryTag());
}
// 通道关闭
$pass->close();
// 链接关闭
$conn->close();
}else{
echo '抱歉没有消息了';exit;
}
}else{
echo '链接失败';
}
}
}
调用生产者跟消费者
// 添加消息
public function addMessage(){
$Queue = new Queue();
for($i=0;$i<10;$i++){
$msg = "这是数字".$i;
$Queue->productionMq("queue","switch",$msg);
}
}
// 取消息
public function getMessage(){
$Queue = new Queue();
while(true) {
$Queue->consumer("queue", function ($message) {
var_dump($message);
// 需要返回值
return true;
});
}
}