Laravel开发store接口 实现每30秒生成随机数直至停止功能求助
现有代码核心问题
- 循环体内创建完第一条记录就执行了
return $Tasks,直接结束了请求进程,循环永远不会执行第二次 while判断条件逻辑完全错误:初始化时你给$startIncrement加了30秒,和当前时间$date本来就不相等,循环只会执行1次就退出- 没有加时间等待逻辑,就算循环能执行,也会瞬间触发大量数据库写入,不会间隔30秒运行
- 单次HTTP请求有超时限制,PHP、Web服务器都默认会主动杀死执行时间过长的请求进程,不可能在单次接口请求里跑无限循环,也没法实现前端点击停止就终止的逻辑
可行实现方案
你需要把定时执行逻辑和HTTP接口解耦,接口只负责控制任务状态,定时生成逻辑放到后台常驻进程执行:
第一步 调整数据表结构
给task_types表新增tinyint类型的status字段,用于标记任务状态:1=运行中,2=已停止
第二步 编写控制接口
运行启动接口:
public function store(Request $request) { date_default_timezone_set('Africa/Nairobi'); $task = TaskType::create([ 'event' => 'START', 'status' => 1, 'actual_time' => now()->format('h:i:s'), 'colors' => 'fff' ]); return $task; }
停止接口:
public function stop(Request $request, int $taskId) { TaskType::where('id', $taskId)->update(['status' => 2]); return response()->json(['code' => 0, 'message' => '任务已停止']); }
第三步 编写后台定时执行逻辑
生成Artisan控制台命令:
php artisan make:command RandomNumberGenerator
编辑命令文件app/Console/Commands/RandomNumberGenerator.php:
<?php namespace App\Console\Commands; use App\Models\TaskType; use Illuminate\Console\Command; class RandomNumberGenerator extends Command { protected $signature = 'random:generate'; protected $description = '每30秒为运行中的任务生成随机数'; public function handle() { date_default_timezone_set('Africa/Nairobi'); while (true) { // 遍历所有运行中的任务生成记录 TaskType::where('status', 1)->each(function ($task) { $generator = rand(10, 20); $programTime = now()->format('h:i:s'); $runningNServers = "Reporting {$generator} servers running at {$programTime}"; TaskType::create([ 'event' => 'RUNNING', 'message' => $runningNServers, 'program_time' => $programTime, 'actual_time' => $task->actual_time, 'display_message' => $runningNServers, 'colors' => 'fff', 'status' => 1 ]); }); // 间隔30秒执行一次 sleep(30); } } }
第四步 启动后台进程
本地开发直接执行命令即可运行:
php artisan random:generate
生产环境可以用Supervisor托管该进程,保证进程异常退出后自动重启。
前端可以轮询任务列表接口拉取最新生成的随机数记录,点击停止按钮时调用停止接口修改任务状态即可终止生成逻辑。
内容的提问来源于stack exchange,提问作者Daniel Kariuki
相关产品推荐
相关产品推荐

