You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel中创建随服务器持续运行的商品库存更新函数

实现持续运行的库存更新逻辑

直接用while(true)死循环在应用进程里是非常不推荐的,会耗尽CPU资源,还可能导致应用无响应。下面是几种生产环境可用的方案:

方案1:定时任务(Cron/Windows任务计划)

这是最常用的方式,通过系统定时任务周期性触发库存更新脚本:

  • 编写独立的PHP脚本update_stock.php,实现核心库存更新逻辑:
<?php
// 连接数据库
$db = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
// 获取需要更新的商品并调整库存
$stmt = $db->prepare("UPDATE products SET quantity = quantity + :updated WHERE need_update = 1");
$stmt->execute([':updated' => $updated]);
?>
  • Linux系统添加Cron任务,比如每分钟执行一次:
* * * * * php /path/to/update_stock.php
  • Windows系统可通过「任务计划程序」设置定期执行该脚本。

方案2:消息队列驱动的异步处理

如果库存更新是基于事件触发(比如订单完成、补货通知),用消息队列更高效:

  • 当有库存更新需求时,将任务发送到消息队列(比如Redis List)
  • 编写守护进程脚本,持续监听队列并处理任务:
<?php
$redis = new Redis();
$redis->connect('localhost', 6379);

while (true) {
    // 阻塞式读取队列,避免空循环浪费CPU
    $task = $redis->brPop('stock_update_queue', 0);
    if ($task) {
        $data = json_decode($task[1], true);
        // 执行库存更新
        $db = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
        $stmt = $db->prepare("UPDATE products SET quantity = quantity + :updated WHERE id = :product_id");
        $stmt->execute([
            ':updated' => $data['updated'],
            ':product_id' => $data['product_id']
        ]);
    }
    // 可选:每次处理后短暂休眠,降低资源占用
    usleep(100000);
}
?>
  • 用nohup或systemd将脚本作为守护进程运行,确保服务器重启后自动恢复:
nohup php /path/to/stock_worker.php > /dev/null 2>&1 &

方案3:常驻进程框架(适合复杂场景)

如果需要更稳定的常驻进程,可使用Swoole/Workerman这类PHP协程框架:

<?php
use Swoole\Timer;

// 初始化Swoole进程
$worker = new Swoole\Process(function ($process) {
    // 每隔5秒执行一次库存更新
    Timer::tick(5000, function () {
        // 库存更新逻辑
        $db = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');
        $stmt = $db->prepare("UPDATE products SET quantity = quantity + :updated WHERE need_update = 1");
        $stmt->execute([':updated' => $updated]);
    });
});

$worker->start();
Swoole\Process::wait();
?>
  • 框架自带进程管理、异常重启机制,比自行编写的while循环更稳定。

核心注意事项

  • 无论用哪种方案,都要添加数据库事务,避免并发更新导致库存数据不一致:
$db->beginTransaction();
try {
    // 库存更新操作
    $db->commit();
} catch (Exception $e) {
    $db->rollBack();
}
  • 避免在循环中重复创建数据库连接,尽量复用连接池或单例连接。

内容的提问来源于stack exchange,提问作者Marzanur Zarif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:31:03