gearman实现任务分发

偶然发现了这个gearman,觉得这玩意儿挺好用,非常适合PHP运行一部分业务。

话不多说,安装一下。

使用apt查找

sudo apt search gearman

找到了这个

gearman/bionic,bionic 1.1.18+ds-1 all
  Distributed job queue

好,开始安装

sudo apt-get install gearman

好,安装完成,然后查看是否运行

ps -ef |grep gearman

发现有在运行

$ ps -ef |grep gearman
gearman   1660     1  0 02:54 ?        00:00:00 /usr/sbin/gearmand --pid-file=/run/gearman/gearmand.pid --listen=localhost --daemon --log-file=/var/log/gearman-job-server/gearmand.log
vagrant   2310  1452  0 02:54 pts/0    00:00:00 grep --color=auto gearman

好,然后开始安装php的扩展(因为我PHP版本是7.4 所以这里直接查7.4的对应版本扩展了)

$ sudo apt search php7.4-gearman
Sorting... Done
Full Text Search... Done
php7.4-gearman/bionic 2.1.0+1.1.2-5+ubuntu18.04.1+deb.sury.org+1 amd64
  PHP wrapper to libgearman

然后开始安装这个扩展

sudo apt-get install php7.4-gearman

安装完毕使用php -m过滤一下看看有没有启用

$ php -m |grep gearman
gearman

发现好了,然后开始建两个文件

add_job.php

<?php
$client = new GearmanClient();
$client->addServer('127.0.0.1', 4730);
$res1 = $client->doBackground('runLaterJob', json_encode(array(
  'uid' => 'test user id',
  'title' => '添加一个需要延时处异步执行的代码标题',
  'body' => '执行这个异步的具体内容',
  'sleep_time' => 2,
)));

再创建一个 work_job.php

<?php
$worker = new GearmanWorker();
$worker->addServer('127.0.0.1', 4730);
$worker->addFunction('runLaterJob', function($job) {
    $data = json_decode($job->workload(), true);
    if (isset($data['sleep_time']) && $data['sleep_time'] > 0) {
      sleep($data['sleep_time']);//如果需要延时 就延时处理
    }
    echo "处理任务 uid:{$data['uid']}--title:{$data['title']}--body:{$data['body']} 成功\n";
});
//死循环等待job提交的任务
while($worker->work());

启动 work_job.php

php work_job.php

屏幕无任何输出,再启动 add_job.php

php add_job.php

然后 add_job.php 迅速跑完了,然后看到 work_job.php 2秒后有输出

处理任务 uid:test user id--title:添加一个需要延时处异步执行的代码标题--body:执行这个异步的具体内容 成功

这里我们可以看到,添加job的人投递任务完毕后可以立刻干别的事情,由work消费job的人来慢慢的处理业务,这就非常适合用来处理那种订单延时关闭的处理业务。

比如说,创建订单后20分钟内不支付则自动释放库存,那么就可以在创建订单的时候投递这样一个job,然后后续的由消费job在设定的20分钟后来处理订单,决定它是否需要释放库存(如果需要支付了就不操作任何动作,如果还没支付,就取消库存,并把订单设置为过期未支付订单)

以往我们在处理这种业务类型的时候用的是crontab来定时查哪些订单需要被关闭,哪些订单需要被释放库存,但这样高度依赖了crontab设定的执行时间的频率,总不能设定为1分钟跑一次吧?如果设定为10分钟一次,比如我们设定为08:00,08:10,08:20等等,就会出现8:00刚跑完定时任务后就下单的用户,他的订单创建时间是08:01,那么对于它而言,08:21分它才应该被关闭,可这个时候08:20的定时任务已经跑完了,那么这个订单就在08:30的定时任务被扫到,等于说它实际上等待了29分钟,这就有了一定程度上的不合理。

而使用这个任务分发,就可以让它的任务在后台躺着被自动处理就可以了。

上一篇:Gearman doBackground()无法与php一起使用


下一篇:与PHP的Gearman – 在工作者的螺纹