假设,我有一个程序叫做foo,我需要用 PHP 去调用这个程序做几个任务,任务之间毫不关联,不同任务传给这个程序的参数不同,任务执行完或者任务执行出错,程序都会退出(当然 exit_code 不同)
我现在的想法是这样的,用 PHP 的 shell_exec 函数,后台方式运行程序:
$bar = shell_exec('nohup /path/to/foo -d <一些参数> 2>&1 1>/path/to/log/<参数的 Hash>.log &');
//下面有些别的程序来处理返回的$bar ,获取程序 PID ,并存进去数据库或者别的什么地方
当前台提交任务(就是提交参数)的时候,就调用上面的脚本去运行 foo 这个程序,拿到 PID 之后再做处理
我的问题是:
1.这个方法有没有更优解?
2.如何得知对应 PID 的程序已经正确执行完毕,或者说,这种情况下,如何检查 exit_code 是否为 0 (因为不确定错误报告会不会输出到 stderr )(附:不确定 jobs 命令能不能做到)?
谢谢各位
忘了一点重要的:这个运行的程序是耗时(比方说,下载东西)的,也就是说我需要某种异步执行的方式
1
howardlau 2023-03-20 20:06:47 +08:00
|
2
dobelee 2023-03-20 23:29:04 +08:00
很多年没写 php 了,之前是用 swoole 来做,起一个 tcp/http 服务接收参数,如果任务时间短可控,直接用 task 模型,否则开多进程。
|
4
panlatent 2023-03-20 23:54:07 +08:00 via iPhone 1
symfony/process
|
5
sxbxjhwm 2023-03-21 02:11:15 +08:00 via Android
推荐 swoole
|
6
maigebaoer 2023-03-21 03:05:53 +08:00 via Android
laravel 有任务队列,功能齐全,可以看官方文档去
|
7
yekern 2023-03-21 09:08:33 +08:00
Laravel Thinkphp 相关的框架都已经有完善的队列体系 随便找个文档看看就能用
|
8
8355 2023-03-21 09:10:30 +08:00
workerman
https://www.workerman.net/doc/workerman/worker/construct.html $task = new Worker(); $task->onWorkerStart = function($task) { 执行你的代码 }; 可以封装成服务 也可以用上面提到的 symfony/process 加到你的现有系统 |
9
xiaoshouchen 2023-03-21 09:25:44 +08:00
pcntl ,PHP 的多进程库
|
10
Seanfuck 2023-03-21 10:24:49 +08:00
多进程嘛,数据 /控制用参数+数据库或文件互通,简单点,开进程用 fsocketopen + ignore_user_abort 去请求 url
|
11
xiaotianhu 2023-03-21 10:26:48 +08:00
非 FPM ,cli 模式可以直接 fork 啊,或者用包装好的 symfony/process
web 服务,简单的可以考虑,本地启个 Redis + 监听 cli 进程,用 Redis 通信,在 cli 里做。 或者直接启动个 cli ,走 unix socket 通信,fpm 把任务发给 cli 去做。 想折腾就 swoole ,异步更完善了。 |
12
MFWT OP @xiaotianhu 懂了,用 PHP 做个 CLI 的,再用 PHP 做和前端通信的 API ,前端访问-》 API 调用 CLI ,配合 PHP 原生的一些函数处理?
|
13
julyclyde 2023-03-26 19:37:58 +08:00
1 有
2 无法。确定 jobs 不行 你应该单独搞一个后台服务器,而不是直接由 php 来运行后台服务 |