在laravel框架中使用mq
本文写于2018-11-28
1、部署laravel项目
https://github.com/laravel/laravel 通过git克隆项目,或者下载zip包然后解压等方式都可以把laravel框架源码下载下来。
然后composer install 安装各种依赖
然后复制.env.example 为.env文件,执行php artisan key:generate 生成APP_KEY
2、上传文件到github【备注:这一步可以略过】
1)git bash 到项目目录,然后git init,初始化本地仓库
2)git remote add origin 远程库地址
3)git add . 把文件缓存到缓冲区
4)git commit -m '初始提交'
5)git push origin master 推送本地代码到远程库master分支
3、安装mq依赖
从 https://packagist.org/?query=rabbitmq 选择一个依赖包

从上面截图看到,能用的就是第一个和最后一个依赖。暂时先使用第一个依赖,后续有时间补充下第二个依赖的使用。
composer require php-amqplib/php-amqplib 即可安装依赖
4、laravel框架中使用mq
1)在config目录下新增mq.php,文件内容:
<?php
return [
'host' => env('MQ_HOST', '127.0.0.1'),
'port' => env('MQ_PORT', 5672),
'user' => env('MQ_USER', 'guest'),
'password' => env('MQ_PASSWORD', 'guest'),
'queue' => env('MQ_QUEUE', 'default'),
'exchange' => env('MQ_EXCHANGE', 'default'),
'key' => env('MQ_KEY', 'default'),
];
具体的配置信息,可以在.env文件中配置,也可以修改这个文件。
2)新增MqSend.php文件,路径:app/Console/Commands
<?php namespace App\Console\Commands; use Illuminate\Console\Command;
use PhpAmqpLib\Connection\AMQPConnection;
use PhpAmqpLib\Message\AMQPMessage; class MqSend extends Command
{
/**
* 控制台命令 signature 的名称。
*
* @var string
*/
protected $signature = 'mq:send {msg}';
/**
* 控制台命令说明。
*
* @var string
*/
protected $description = 'send messages to rabbitMQ'; /**
* 创建一个新的命令实例。
*
* @return void
*/
public function __construct()
{
parent::__construct();
} /**
* 执行控制台命令。
*
* @return mixed
*/
public function handle()
{
$host = config('mq.host');
$port = config('mq.port');
$user = config('mq.user');
$password = config('mq.password');
$queue = config('mq.queue'); // 队列名称
$exchange = config('mq.exchange'); // 交换机名称
$key = config('mq.key'); // 队列绑定交换机时配置的routingKey $connection = new AMQPConnection($host, $port, $user, $password);
$channel = $connection->channel(); /**
* 如果管理后台上已经配置了交换机、队列,以及绑定了关系,则不需要下面的3条语句
*/
$channel->exchange_declare($exchange, 'direct', false, true, false); // 初始化交换机
$channel->queue_declare($queue, false, true, false, false); // 初始化队列
$channel->queue_bind($queue, $exchange, $key); // 将队列与某个交换机进行绑定,并使用路由关键字 $msg = '[' . date('Y-m-d H:i:s') . '] ' . $this->argument('msg');
$data = new AMQPMessage($msg, ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
$channel->basic_publish($data, $exchange, $queue);
echo "[X] Sent: $msg \n"; $channel->close();
$connection->close();
}
}
3)新增MqReceive.php文件, 路径:app/Console/Commands
<?php namespace App\Console\Commands; use Illuminate\Console\Command;
use PhpAmqpLib\Connection\AMQPConnection;
use PhpAmqpLib\Message\AMQPMessage; class MqReceive extends Command
{
/**
* 控制台命令 signature 的名称。
*
* @var string
*/
protected $signature = 'mq:receive';
/**
* 控制台命令说明。
*
* @var string
*/
protected $description = 'receive messages to rabbitMQ'; /**
* 创建一个新的命令实例。
*
* @return void
*/
public function __construct()
{
parent::__construct();
} /**
* 执行控制台命令。
*
* @return mixed
*/
public function handle()
{
$host = config('mq.host');
$port = config('mq.port');
$user = config('mq.user');
$password = config('mq.password');
$queue = config('mq.queue'); // 队列名称
$exchange = config('mq.exchange'); // 交换机名称
$key = config('mq.key'); // 队列绑定交换机时配置的routingKey $connection = new AMQPConnection($host, $port, $user, $password);
$channel = $connection->channel(); /**
* 如果管理后台上已经配置了交换机、队列,以及绑定了关系,则不需要下面的3条语句
*/
$channel->queue_declare($queue, false, true, false, false); echo ' [*] Waiting for messages. To exit press CTRL+C', "\n"; $callback = function($msg) {
echo " [x] Received ", $msg->body, "\n";
}; $channel->basic_consume($queue, '', false, true, false, false, $callback); while(count($channel->callbacks)) {
$channel->wait();
} $channel->close();
$connection->close();
}
}
4)修改app/console/Kernel.php文件,在$commands数组中增加:
protected $commands = [
Commands\MqSend::class,
Commands\MqReceive::class,
];
这样子就能在php artisan看到有mq的命令:

5)生产者发布消息

发布成功。代码中设置了交换机、队列名、理由关键词,这些默认值都是default,在rabbitMQ管理后台可以看到有新增了交换机、队列,队列里面也有消息。
【备注】windows系统上可能执行生产者脚本会报错:

这是因为windows不支持这个SOCKET_EAGAIN常量。
参考:https://github.com/php-amqplib/php-amqplib/issues/619

要改下vendor/php-amqplib/php-amqplib/PhpAmqpLib/Wire/IO/StreamIO.php文件:
// self::$ERRNO_EQUALS_EAGAIN = 'errno=' . SOCKET_EAGAIN;
// windows不支持SOCKET_EAGAIN,所以会出现未定义的报错。在linux上SOCKET_EAGAIN是SOCKET_EWOULDBLOCK的别名
// https://github.com/php-amqplib/php-amqplib/issues/619 使用SOCKET_EWOULDBLOCK替换
self::$ERRNO_EQUALS_EAGAIN = 'errno=' . (defined('SOCKET_EAGAIN') ? SOCKET_EAGAIN : SOCKET_EWOULDBLOCK);
self::$ERRNO_EQUALS_EWOULDBLOCK = 'errno=' . SOCKET_EWOULDBLOCK;
self::$ERRNO_EQUALS_EINTR = 'errno=' . SOCKET_EINTR;
修改完之后就没问题了。
6)消费者接收消息

消息有2条,都接收到了。按Ctrl+C可以退出消费者,因为消费是阻塞,一直在等待接收消息。
5、参考文档:
1)laravel中新增artisan命令:https://laravel-china.org/docs/laravel/5.7/artisan/2276
2)laravel中使用 php-amqplib/php-amqplib 依赖包
https://segmentfault.com/a/1190000012308675
https://segmentfault.com/a/1190000011825148
在laravel框架中使用mq的更多相关文章
- laravel框架中所用到的依赖注入
用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概 ...
- Laravel框架中的数据库CURD操作、连贯操作、链式操作的用法
Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁.富于 ...
- laravel框架中Job和事件event的解析
本篇文章给大家带来的内容是关于laravel框架中Job和事件event的解析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在做项目的时候,一直对Job和Event有个疑惑.感觉两 ...
- laravel框架中超实用的功能介绍
本篇文章给大家带来的内容是关于laravel框架中超实用的功能介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 让lumen的dd() dump()像laravel一样优雅 1 c ...
- Laravel框架中Echo的使用过程
今天的这篇文章中给大家分享关于laravel框架中echo的使用,文章的内容是一步一步来的,用了16步走完一个过程,过程很清晰,希望可以帮助到有需要的朋友吧.话不多说,直接看内容.官方文档推荐使用 P ...
- laravel框架中使用QueryList插件采集数据
laravel框架中使用queryList 采集数据 采集数据对我们来说真家常便饭,那么苦苦的写正则采集那么一点点东西,花费了自己大把的时间和精力而且没有一点技术含量,这个时候就是使用我们的好搭档Qu ...
- laravel框架中的session问题
这两天一直在鼓捣服务器,配置环境,在搭建laravel的过程之中,发现了laravel中的session的一些问题,这里总结一下: (1):我在服务器上搭建了多个sever,为了测试学习,分别使用不同 ...
- Laravel框架中的make方法详解
为什么网上已经有这么多的介绍Laravel的执行流程了,Laravel的容器详解了,Laravel的特性了,Laravel的启动过程了之类的文章,我还要来再分享呢? 因为,每个人的思维方式和方向是不一 ...
- Laravel框架中实现supervisor执行异步进程
问题描述:在使用Laravel框架实现动态网页时,若有些操作计算量较大,为了不影响用户体验,往往需要使用异步方式去处理.这里使用supervisor和laravel自带的queues实现. Super ...
随机推荐
- 关于Vue 刷新页面
前言 Vue 中是单页面,当然需要刷新数据咯 你一定遇到这样的需求::比如在删除或者增加一条记录的时候希望当前页面可以重新刷新或者 这个页面有个组件 ,但是这个组件里面的点击事件还是到当前页面 怎么就 ...
- 【NOIP2016提高A组五校联考1】排队
题目 分析 首先预处理出每个点的优先级,当有一个人进入时,一定会走到优先级最大的空房间中. 把所有空的房间扔到一个堆中,按优先级大小维护这个堆. 答案怎么求就不说了,很容易想到,就只讲操作吧. 对于第 ...
- Mybatis-Plus和Mybatis的区别
1.List item 区别一如果Mybatis Plus是扳手,那Mybatis Generator就是生产扳手的工厂.通俗来讲——MyBatis:一种操作数据库的框架,提供一种Mapper类,支持 ...
- guava中Multimap、Multiset使用
guava中的Multimap接口 Multimap和java.util.Map接口没有任何继承关系.同Map一样,也是放键值对,但是Multimap的值是一个集合.同样支持泛型,假如键值对的key的 ...
- AJAX - 服务器 响应
AJAX - 服务器 响应 服务器响应 如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性.大理石构件来图加工 属性 描 ...
- 【Leetcode】二叉树的最小深度
题目: 给定一个二叉树,找出其最小深度. 注意最小深度的定义! 最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明: 叶子节点是指没有子节点的节点. 一.递归法 时间复杂度:O(n).需要 ...
- 一个ros包依赖另一个ros包提供的库
背景: 编写一个点云配准的ros包,记为A,在其中打算使用多种点云配准算法. 同一个ros工作空间下有另一个ros包,记为B,B中提供了几种点云配准算法,并将它们都编译成一个库文件并安装在工作空间中. ...
- Vue CLI4.0版本正式发布了!一起来看看有哪些新的变化吧
Vue CLI4.0版本正式发布 这个主要的版本更新主要关注底层工具的必要版本更新.更好的默认设置和其他长期维护所需的微调. 我们希望为大多数用户提供平稳的迁移体验. Vue CLI v4提供了对Ni ...
- 详细讲解Android中的Message的源码
相信大家对于Android中的Handler是在为熟悉不过了,但是要知道,Handler就其本身而言只是一个壳子,真正在内部起到作用的是Message这个类,对于Message这个类,相信大家也不会陌 ...
- BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4422 我真服了..这题我能调一天半,最后还是对拍拍出来的...脑子还是有病啊 题解: ...