1:拉取composer包
composer require php-amqplib/php-amqplib
//注意php 安装php-amqplib需要有amqp、bcmath这个拓展
2.在config/queue.php 文件中配置信息
'rabbitmq' => [
'driver' => 'rabbitmq',
'host' => env('RABBITMQ_HOST', '43.143.96.235'),
'port' => env('RABBITMQ_PORT', 5672),
'username' => env('RABBITMQ_USER', 'admin'),
'password' => env('RABBITMQ_PASSWORD', 'admin'),
'vhost' => env('RABBITMQ_VHOST', '/'),
'options' => [
'ssl_options' => [
'verify_peer' => false,
],
],
],
'default' => env('QUEUE_CONNECTION', 'rabbitmq'),
4:封装rabbitmq生产消费类
config('rabbitmq.host'),
'port' => config('rabbitmq.port'),
'user' => config('rabbitmq.user'),
'password' => config('rabbitmq.password'),
'vhost' => '/',//默认虚拟主机
];
return $this->connection = new AMQPStreamConnection($config['host'],$config['port'],$config['user'],$config['password'],$config['vhost']);
}
/**
* 数据插入到mq队列中(生产者)
* @param $queue .队列名称
* @param $messageBody .消息体
* @param string $exchange .交换机名称
* @param string $routing_key .设置路由
* @throws \Exception
*/
public function push($queue,$exchange,$routing_key,$messageBody)
{
//构建通道(mq的数据存储与获取是通过通道进行数据传输的)
$channel = $this->connection->channel();
//声明一个队列
$channel->queue_declare($queue, false, true, false, false);
//指定交换机,若是路由的名称不匹配不会把数据放入队列中
$channel->exchange_declare($exchange,'direct',false,true,false);
//队列和交换器绑定/绑定队列和类型
$channel->queue_bind($queue,$exchange,$routing_key);
$config = [
'content_type' => 'text/plain',
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
];
//实例化消息推送类
$message = new AMQPMessage($messageBody,$config);
//消息推送到路由名称为$exchange的队列当中
$channel->basic_publish($message,$exchange,$routing_key);
dump('生产者已操作');
//关闭消息推送资源
$channel->close();
//关闭mq资源
$this->connection->close();
}
/**
* 消费者:取出消息进行消费,并返回
* @param $queue //队列名称
* @param $callback //回调函数,处理队列里的消息
* @return bool
* @throws \Exception
*/
public function pop($queue, $callback)
{
print_r('消费者中心'.PHP_EOL);
//连接到 RabbitMQ 服务器并打开通道
$channel = $this->connection->channel();
//声明要获取内容的队列
$channel->queue_declare($queue, false, true, false, false);
//获取队列信息(消息总条数)
$countQueue = $channel->queue_declare($queue, true)[1];
//获取队列中的下一条消息
$msg = $channel->basic_get($queue);
//确认消费消息
$channel->basic_ack($msg->delivery_info['delivery_tag']);//消息主题返回给回调函数
//消息主题返回给回调函数
$res = $callback($msg->body);
if($res){
print_r('ack验证'.PHP_EOL);
//ack验证,如果消费失败了,从新获取一次数据再次消费
$channel->basic_ack($msg->getDeliveryTag());
}
print_r('ack消费完成'.PHP_EOL);
$channel->close();
$this->connection->close();
return true;
}
}
4: 创建jobs文件 使用laravel的队列监听
php artisan make:job SmsProduct
5: 在UpdateProduct.php中编写生产者与消费者
生产者在把消息推送到laravel的事件监听中,初始化生产者配置,创建rabbitmq的所需要绑定的交换机,路由,队列,并且进行绑定。并且监听消费者,当有消息消费时,则从rabbitmq的队列中获取消息,消费成功进行ack
productKey = '发送的id'.$data->id;
$rabbitmq = new RabbitmqServer();
$rabbitmq->push('sendsms','exc_sms','pus_sms',$data);
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
$rabbitmq = new RabbitmqServer();
$rabbitmq->pop('sendsms',function ($message){
//调用发送短信方法,成功返回ture 或者 false
});
}
}
6:在控制器给生产者派遣任务
public function production(Request $request)
{
try {
$data = DoctorModel::first();
$send = new SendSPodcast($data);
$this->dispatch($send);
return true;
}catch (\Exception $e) {
return $this->witejson(1001,'null',$e->getMessage());
}
}
7:消费者监听消息
php artisan queue:work rabbitmq