ThinkPHP+redis 实现延迟任务 实现自动取消订单,自动完成订单
在 ThinkPHP 中结合 Redis 实现延迟任务,可以用于自动处理订单取消、自动完成等功能。Redis 的 ZSET
(有序集合)功能非常适合实现延迟任务队列。以下是详细的实现步骤:
1. 准备工作
确保你的环境中已安装 Redis,并在 ThinkPHP 中配置 Redis 连接。
配置 Redis(假设使用 Redis 扩展):
在 config/database.php
中配置 Redis 连接:
return [
// ...
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'persistent' => false,
],
];
2. 添加延迟任务
通过 Redis 的有序集合(Sorted Set)来实现延迟任务。任务会在指定的时间戳后执行。
任务添加函数:
namespace app\index\model;
use think\Model;
use think\facade\Cache;
class TaskModel extends Model
{
// 添加延迟任务
public function addDelayedTask($taskId, $delaySeconds, $taskData)
{
$redis = Cache::store('redis')->handler();
$timestamp = time() + $delaySeconds;
$redis->zAdd('delayed_tasks', $timestamp, json_encode([
'task_id' => $taskId,
'task_data' => $taskData
]));
}
}
3. 执行延迟任务
创建一个定时任务脚本,定期检查 Redis 队列并执行到期的任务。
任务执行脚本(命令行):
namespace app\command;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\facade\Cache;
class ProcessDelayedTasks extends Command
{
protected function configure()
{
$this->setName('process:delayed-tasks')
->setDescription('Process delayed tasks from Redis.');
}
protected function execute(Input $input, Output $output)
{
$redis = Cache::store('redis')->handler();
$now = time();
// 获取当前时间之前的所有任务
$tasks = $redis->zRangeByScore('delayed_tasks', '-inf', $now);
foreach ($tasks as $taskJson) {
$task = json_decode($taskJson, true);
$taskId = $task['task_id'];
$taskData = $task['task_data'];
// 执行任务
$this->processTask($taskId, $taskData);
// 从 Redis 中删除已处理的任务
$redis->zRem('delayed_tasks', $taskJson);
}
}
private function processTask($taskId, $taskData)
{
// 根据 taskId 和 taskData 处理任务
// 例如:自动取消订单、自动完成订单等
// 这里可以调用其他模型或服务来处理具体逻辑
$output->writeln("Processing task ID: $taskId");
// 实现你的任务处理逻辑
}
}
定时任务配置:
在服务器上使用 Cron 或类似的定时任务工具定期运行 process:delayed-tasks
命令。例如,每分钟运行一次:
* * * * * /usr/bin/php /path/to/your/project/think process:delayed-tasks
4. 处理具体任务
你可以根据具体需求实现任务处理逻辑。例如,实现自动取消订单和自动完成订单功能:
自动取消订单:
public function autoCancelOrder($orderId)
{
// 根据订单 ID 查询订单状态并进行取消操作
$order = OrderModel::find($orderId);
if ($order && $order->status === 'pending') {
$order->status = 'canceled';
$order->save();
// 可能需要发送通知等
}
}
自动完成订单:
public function autoCompleteOrder($orderId)
{
// 根据订单 ID 查询订单状态并进行完成操作
$order = OrderModel::find($orderId);
if ($order && $order->status === 'shipped') {
$order->status = 'completed';
$order->save();
// 可能需要发送通知等
}
}
总结
- 添加延迟任务:使用 Redis 的有序集合将任务添加到 Redis 队列中,指定延迟时间。
- 执行延迟任务:创建定时任务脚本定期检查 Redis 队列并执行到期的任务。
- 处理具体任务:根据任务类型实现具体的业务逻辑,比如自动取消订单或自动完成订单。