偶然发现了这个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++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分钟,这就有了一定程度上的不合理。
而使用这个任务分发,就可以让它的任务在后台躺着被自动处理就可以了。