2

几小时前刚刚发布的 Larevel 5.0 为队列功能提供了官方原生的database驱动器,完全取代了本软件包的功能。

对于Laravel 5及以上版本,本文的内容及所涉软件包均已失效,请勿实践。未来也不会再有l5mysqlqueue软件包。

shamiao/l4mysqlqueue软件包完成了他的使命。我们永远怀念他。

沙渺,2015年2月4日。


laravel 4是一个高度依赖包管理器与命令行界面的php框架。不使用composerphp artisan两个工具几乎寸步难行。……不过这也并不意味着laravel就是虚拟主机没戏,必须VPS/云主机起跳的“小网站杀手”。

其实在cPanel虚拟主机上,部署laravel并不是那么难的事情,因为仁慈的cPanel面板,一般都开放有操作Linux原生cron jobs的设置页面。

只要有了cron这个口子,就可以获得执行命令行任务的机会,每分钟1次——这已经足够了。

但是实际使用中发现,laravel的其他功能都没毛病,就是异步队列根本不能用。考察laravel提供的原生异步队列驱动器,没有一个适合在虚拟主机环境中使用:

  • 同步(sync):只是残废的调试工具
  • Beanstalkd:虚拟主机不会有
  • Redis:虚拟主机不会有
  • IronMQ:要美元
  • Amazon SQS:要美元

我考虑了很多方案(包括一些很土炮的馊主意),最终还是遵守了laravel的哲学[注A],写了一个原生的MySQL队列驱动器。

原理

就是数据库一张表。加入任务时写入,执行任务时检索,需要删除时打标记(软删除)。

即使使用Queue::later()推迟任务,任务信息也会立刻写入表格,而不设计“主动推迟一定时间再写入”的复杂。表格中记录有任务的执行时刻,没到时间的任务会在检索时被自然忽略。

性能确实低下(受制于MySQL),绝对禁止用于大数量、高密度任务的场合。但是部署极其简易,所以很适合小网站、偶发性、时效性不强的异步任务。

特点

100%完整实现,Laravel文档规定的用法全部支持。具体而言:

  • 支持原生的queue:listen, queue:work等 artisan 队列操作
  • 不在 artisan 上画蛇添足去定义额外的命令
  • 支持记录重试次数,正确对接laravel的失败任务回收系统
  • 支持任意多个队列,支持自定义默认队列名称
  • 只占用1个数据表,支持自定义表名,允许数据库有表前缀
  • 不使用Eloquent ORM

安装

composer.json 增加以下依赖包,并做 composer update [注B]

"shamiao/l4mysqlqueue": "~1.0"

编辑 config/app.php 增加 provider 条目:

'Shamiao\L4mysqlqueue\L4mysqlqueueServiceProvider'

编辑 config/queue.php 设置队列驱动器:

'default' => 'mysql', // 这个是连接名,随意。惯例是写成和驱动器同名的'mysql'

'mysql' => array(          // 这个和'default'右边那个一致就好
    'driver' => 'mysql',   // 驱动器名,这里就必须写成'mysql'了!
    'queue'  => 'default', // 如有需要,可以指定默认队列名,推荐直接删去不写
    'table'  => 'queue','  // 如有需要,可以指定表格名,推荐直接删去不写
),

最后把本软件包(package)附带的迁移操作(migrations)并入数据库[注C]

php artisan migrate --package="shamiao/l4mysqlqueue"

使用

没什么好说的。这个驱动器对用户而言是透明的,所以Laravel文档的Queue页面怎么说就可以怎么做。

是完整实现,所以文档中提到的功能全都没有禁忌。

如果在虚拟主机环境下,运行一个必须持续跑着的 queue:listenqueue:work --daemon 不方便,也可以像这样利用cron来变通的执行[注D]

* * * * * ( cd /home/username/your/laravel/dir; php artisan queue:work --tries=3 )

当然代价就是每分钟只能执行一个任务了。

注意

  • 删除任务时只打标记做软性删除,所以数据表queue必然只膨胀不减小。请记得自拟计划,在负载不高时把status = 'deleted'的任务真正的DELETE掉。
  • 很多实现还会调整,如有任何变化请以GitHub说明为准。

链接

From GitHub and Composer with love:

本项目代码均为独立,开发过程受到过两个不完善实现 barryvdh/laravel-async-queueoctoberrain/cron 的启发。

注释

  • A:①要艺术,不要把代码写的很“脏”。 ②接口遍地都是,有需要,就扩展。
  • B: 虚拟主机肯定不会提供composer。你需要自己下载composer.phar,放到主文件夹下边,然后执行php /home/username/composer.phar update
  • C: 根据主机环境不同,可能部分主机要用php5代替php,也可能有部分主机没有PATH变量,必须手动打/usr/bin/php完整路径。
  • D:不妨写成.sh脚本文件并设置权限755,这样在cron job里只需要指定脚本完整路径即可,日后修改也方便。

沙渺
21.8k 声望1.1k 粉丝

1998年入行,普通的电脑老玩家。Web、嵌入式Linux和电子产品设计研究者。