前提:
1.已安装rabbitmq(本demo的rabbitmq版本是:3.9.15) ,可参考:windows10环境下的RabbitMQ安装步骤(图文)_镇杰。的博客-CSDN博客
2.php开启amqp扩展(本demo的php版本是:php7.3.4nts)
具体步骤:
1.在本地对应代码项目请求一下,推送mq的方法:http://local.test.com/index.php?com=test&t=testLocalPush
,再看看rabbit管理后台:http://localhost:15672/#/queues ,对应的队列数据就出来了
2.在本地对应代码项目请求一下,消费mq的方法(单条):
http://local.test.com/index.php?com=test&t=testLocalGet
,再看看rabbit管理后台:http://localhost:15672/#/queues ,每个队列都被消费了1条数据
3.在本地对应代码项目请求一下,消费mq的方法(队列中所有数据):
http://local.test.com/index.php?com=test&t=testLocalPush
,再看看rabbit管理后台:http://localhost:15672/#/queues ,指定队列中所有数据都别消费了
4.按照以上模式,有什么好奇想看效果的,可以自己写demo调试
/**
* 测试推送数据进mq队列
* @return void
*/
public function testLocalPush()
{
var_dump($this->publish('exchange_sanguo_weiguo', array('司马懿', 'zhangfei', '男', 30), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('司马昭', 'zhangfei', '男', 31), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('曹操', 'zhangfei', '男', 32), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('夏侯惇', 'zhangfei', '男', 33), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('许褚', 'zhangfei', '男', 34), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('黄盖', 'zhangfei', '男', 29), 'weiguo'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('test', 'zhangfei2222', '男', 29), 'weiguo2'), '<br />');
var_dump($this->publish('exchange_sanguo_weiguo', array('test', 'zhangfei3333', '男', 29), 'weiguo3'), '<br />');
var_dump($this->publish('exchange_sanguo_shuguo', array('张飞', 'zhangfei', '男', 20), 'shuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_shuguo', array('关羽', 'zhangfei', '男', 21), 'shuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_shuguo', array('黄忠', 'zhangfei', '男', 22), 'shuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_shuguo', array('赵云', 'zhangfei', '男', 23), 'shuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_shuguo', array('马超', 'zhangfei', '男', 24), 'shuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_wuguo', array('周瑜', 'zhangfei', '男', 25), 'wuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_wuguo', array('孙权', 'zhangfei', '男', 26), 'wuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_wuguo', array('孙策', 'zhangfei', '男', 27), 'wuguo'), '<br />');
var_dump($this->publish('exchange_sanguo_wuguo', array('陆逊', 'zhangfei', '男', 28), 'wuguo'), '<br />');
exit();
}
/**
* 测试获取mq队列数据
* @return void
*/
public function testLocalGet(){
var_dump($this->get('exchange_sanguo_weiguo', 'queue_weiguo', 'weiguo'), '<br />');
var_dump($this->get('exchange_sanguo_shuguo', 'queue_shuguo', 'shuguo'), '<br />');
var_dump($this->get('exchange_sanguo_wuguo', 'queue_wuguo', 'wuguo'), '<br />');
var_dump($this->get('exchange_sanguo_weiguo', 'queue_weiguo', 'weiguo2'), '<br />');
var_dump($this->get('exchange_sanguo_weiguo', 'queue_weiguo3', 'weiguo3'), '<br />');
}
/**
* 测试消费mq队列数据
* @return void
*/
public function testLocalConsume()
{
var_dump($this->consume('exchange_sanguo_shuguo', 'queue_shuguo', 'shuguo'));
}
/**
* 获取连接
* @return void
*/
public function connect()
{
try {
$this->connect->connect();
} catch (Exception $exception) {
var_dump($exception->getMessage());
exit();
}
}
/**
*
* 断开连接
* @return void
*/
public function disconnect()
{
$this->connect->disconnect();
}
/**
* 推送消息
* @param string $exchange_name 交换机名称
* @param array $message 消息
* @param string $routing_key routing_key
* @return bool
*/
public function publish($exchange_name = 'exchange', $message = array(), $routing_key = '')
{
$result = false;
try {
$this->connect();
// 创建channel
$channel = new AMQPChannel($this->connect);
// 创建交换机
$ex = new AMQPExchange($channel);
// 创建或选择交换机,不存在则添加一个
$ex->setName($exchange_name);
// 交换机类型
// direct类型交换机 (直连交换机) // define(‘AMQP_EX_TYPE_DIRECT‘, ‘direct‘);
// fanout类型交换机 (扇型交换机)// define(‘AMQP_EX_TYPE_FANOUT‘, ‘fanout‘);
// topic类型交换机 (主题交换机)// define(‘AMQP_EX_TYPE_TOPIC‘, ‘topic‘);
// header类型交换机 (头交换机)// define(‘AMQP_EX_TYPE_HEADERS‘, ‘headers‘);
$ex->setType(AMQP_EX_TYPE_DIRECT);
// 持久化交换机和队列,当代理重启动后依然存在,并包括它们中的完整数据 // define(‘AMQP_DURABLE‘, 2);
$ex->setFlags(AMQP_DURABLE);
$ex->declareExchange();
// 推送消息
$result = $ex->publish(json_encode($message), $routing_key);
$this->disconnect();
} catch (Exception $exception) {
var_dump($exception->getMessage());
exit();
}
return $result;
}
/**
* mq消费(首条数据)
* @param string $exchange_name
* @param string $queue_name
* @param string $routing_key
* @return mixed
*/
public function get($exchange_name = 'exchange', $queue_name = 'queue', $routing_key = '')
{
$message = array();
try {
$this->connect();
// 创建channel
$channel = new AMQPChannel($this->connect);
// 创建列队
$q = new AMQPQueue($channel);
// 设置列队名称,不存在则添加一个
$q->setName($queue_name);
// 持久化交换机和队列,当代理重启动后依然存在,并包括它们中的完整数据 // define(‘AMQP_DURABLE‘, 2);
$q->setFlags(AMQP_DURABLE);
// 声明一个新队列
$q->declare();
// 将给定的队列绑定到交换机上
$q->bind($exchange_name, $routing_key);
//消息获取 当在队列get方法中作为标志传递这个参数的时候,消息将在被服务器输出之前标志为acknowledged (已收到)
$messages = $q->get(AMQP_AUTOACK);
if ($messages){
$message = json_decode($messages->getBody(), true);
}
$this->disconnect();
} catch (Exception $exception) {
var_dump($exception->getMessage());
exit();
}
return $message;
}
/**
* mq消费(全部队列数据)
* @param string $exchange_name
* @param string $queue_name
* @param string $routing_key
* @return mixed
*/
public function consume($exchange_name = 'exchange', $queue_name = 'queue', $routing_key = '')
{
$e_name = $exchange_name; //交换机名,和服务端一致
$k_route = $routing_key; //路由key,和服务端一致
$q_name = $queue_name; // 队列名称
$message = array();
try {
// 1.创建连接和channel
$this->connect();
// 2.在连接内创建一个通道
$channel = new AMQPChannel($this->connect);
// 3.创建交换机
$ex = new AMQPExchange($channel);
$ex->setName($e_name);
// 4.设置交换机类型
//AMQP_EX_TYPE_DIRECT:直连交换机
//AMQP_EX_TYPE_FANOUT:扇形交换机
//AMQP_EX_TYPE_HEADERS:头交换机
//AMQP_EX_TYPE_TOPIC:主题交换机
$ex->setType(AMQP_EX_TYPE_DIRECT);
// 5.设置交换机持久
$ex->setFlags(AMQP_DURABLE);
// 6.声明交换机并输出状态
echo "Exchange Status:" . $ex->declareExchange() . "\n";
// 7.创建队列
$q = new AMQPQueue($channel);
$q->setName($q_name);
//设置队列持久
$q->setFlags(AMQP_DURABLE);
// 8.声明消息队列并输出状态
echo "Message Total:" . $q->declareQueue() . "\n";
// 9.绑定交换机与队列,并指定路由键
echo 'Queue Bind: ' . $q->bind($e_name, $k_route) . "\n";
// 10.设置消息队列消费者回调方法,并进行阻塞
echo "waiting reeive Message...\n";
// 11.接收消息并进行处理的回调方法
function processMessage($envelope, $queue)
{
//取消息内容
$msg = $envelope->getBody();
$message[] = $msg;
//**********此处可以写处理数据的业务代码***************
echo $msg . "\n"; //处理消息
//*****************************************************
//显式确认,队列收到消费者显式确认后,会删除该消息
$queue->ack($envelope->getDeliveryTag());
}
//设置消息队列消费者回调方法,并进行阻塞
$q->consume('processMessage');
// 12. 关闭连接
$this->disconnect();
} catch (Exception $exception) {
var_dump($exception->getMessage());
exit();
}
return $message;
}