Re: [请益] 背景执行相关问题

楼主: GALINE (天真可爱CQD)   2020-02-05 03:24:31
※ 引述《b90022790 (PomeloLaLa)》之铭言:
: 各位php板上的各位前辈好!
: 目前在架设一个简单的订单系统,有个功能无法顺利完成,希望前辈们能给些意见,谢谢
: 环境:php7.4.1、 MySQL、CentOS 6.8
: 功能:当商家按钮确认订单后,除了修改MySQL内容外,希望能够寄mail通知客户
: 问题:使用PHPMailer接gmail SMTP,然而速率过慢,商家的client端需要等待执行完毕
: 才能看到确认后的结果,希望能先让商家看到结果,寄信的功能在服务器背景执行。
: 试过的解决方式:先写一个send.php专门处理寄信的功能,在商家client的页面直接显示
: 确认订单后的结果画面,并在商家该php页面使用system()执行send.php,程式码如下:
: system("php send.php user"); //user为收信者参数
: 然而这仍然会等待执行完才会回responce。
: 使用“php 背景执行 超时”当关键字,采用将结果输出到.out,改system()程式码如下:
: system("php send.php user > MAIL.out");
: 然而这样却变成连寄信都没有执行就结束了。
: 希望前辈们能给一些如何处理该功能的意见,以及为何该system()无法正常执行
: 谢谢各位前辈!还请各位指点!!
php send.php user > MAIL.out
只会把 send.php 的输出(stdout)写进 MAIL.out,没有异步执行的效果
结果会不一样,也许是 wwwuser 没有资料夹写入权限,所以指令直接喷掉
要异步执行东西,直觉是 pcntl_fork()
$pid = pcntl_fork();
if ($pid === 0) {
// 我是 fork 出来的 process,不会卡住娘亲 process 执行
// 在这里寄信
system("php send.php user");
exit; // 寄完信就 exit,不然会一路执行到网页内容整个印出来
}
// 我是原本的 process,或是 fork 失败
// 继续做网页该做的事情
缺点是不熟的人容易不小心写出惊人的 bug
像是不小心 fork 了一万个 process 然后整台机器被 process 噎死
这算是妖术,土炮或是很小的东西可以这么干
如果工作上有人对网页服务发这样的 MR 给我 review,我会热烈地给予关切
推荐做法是,不要在网页里面直接处理这件事
把你要寄信的资料先记录在某个地方,档案也好 DB 也好。
然后跑一只其他的程式在后面等著,或是设定 cron job 定时去读
看到有资料的时候依序寄信然后把资料清空,如果没有新资料就回去睡觉
更上道的做法,是去研究 message queue / job queue
============
另,如果想用 PHP 写 cli 指令,有个小地方可以参考
像这样透过第一行的 hashbang 告诉 shell 要呼叫 php 来执行这只程式
#!/usr/bin/env php
<?php
echo "I am a command\n";
然后把这只 php 设定为可执行档案
$ chmod +x command.php
就可以把这只 code 当成 shell script 来跑了
$ ./command.php
I am a command
作者: b90022790 (柚子拉拉)   2020-02-05 16:44:00
非常谢谢您的回文,让我学到不少东西跟想法。目前已经确认是我真的忘了更改档案写入的权限XD,然后加一个&在指令的后面让Linux在背景执行,这已经可以达成目的。其他您提到的方法,在未来我会努力将其实现到我的专案里,希望能够成为像您一样有经验、有想法的工程师,谢谢您!
作者: kancu (光辉的六翼)   2020-02-06 16:15:00
我也建议把寄信的部份由另一支程式定期处理,用&来丢背景其实是一件很恐布的事情,如果寄信的那支php没写好,服务器上很有机会不断的累积被强制丢在背景执行的寄信用程式,然后等累积到一定程度,主机就当了另一方面,这种丢背景的方式等于提供了一种资安攻击的方法只要不断的在商店端一直丢完成的讯号,背景执行的程式就会一直累积(因为你都说接gmail SMTP很慢,所以一定会累积),然后主机就当掉了用另一只程式来跑还有可以简单平行处理的优点,用OpenMP来平行处理寄信的问题,即使累积很多要寄的资料也可以很快
作者: JohnRoyer (Zero 日落)   2020-04-21 11:35:00
我记得原 PO 有 fork 到机器炸掉的记录 XDGithub 其实有一些不错用的套来管理 fork /process像是 neovim/neovim 感觉就还不错用抱歉贴错了,这个才是处理 fork 的:github kriswallsmith/spork

Links booklink

Contact Us: admin [ a t ] ucptt.com