PHP后台守护进程的实现方式(Linux环境)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
应用场景
某些情况下,我们需要持续的周期性的提供一些服务,比如监控内存或cpu的运行状况,这些应用与客户端是没有关系的,不是说客户端(如web界面,手机app等)关闭了,我们就不监控内存或cpu了,为了应对这种业务场景,后台守护进程就可以派上用场了。
所需环境
实现方式
在/usr/local/src/目录下,新建一个daemon.php脚本文件,内如如下:
1.<?php
2.
3.Class Daemon{
4.
5./**
6. * 初始化一个守护进程
7. * @throws Exception
8. */
9.public function init(){
10.//创建一个子进程
11.$pid = pcntl_fork();
12.
13.if ($pid == -1) {
14.throw new Exception('fork子进程失败');
15. } elseif ($pid > 0) {
16.//父进程退出,子进程变成孤儿进程被1号进程收养,进程脱离终端
17. exit(0);
18. }
19.
20.//创建一个新的会话,脱离终端控制,更改子进程为组长进程
21.$sid = posix_setsid();
22.if ($sid == -1) {
23.throw new Exception('setsid fail');
24. }
25.
26.//修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释
放对父进程工作目录的占用。
27. chdir('/');
28.
29./**
30. * 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话
组长可以申请重新打开一个终端,为了避免
31. * 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是
会话组长。
32. */
33.$pid = pcntl_fork();
34.if ($pid == -1) {
35.throw new Exception('fork子进程失败');
36. } elseif ($pid > 0) {
37.//再一次退出父进程,子进程成为最终的守护进程
38. exit(0);
39. }
40.//由于守护进程用不到标准输入输出,关闭标准输入,输出,错误输出描述符
41. fclose(STDIN);
42. fclose(STDOUT);
43. fclose(STDERR);
44. }
45.}
46.
47.$daemon = new Daemon();
48.$daemon->init();
49.
50.//处理业务代码
51.while(true) {
52. file_put_contents('/usr/local/src/log.txt', time().PHP_EOL, FILE_APPEND)
;
53. sleep(5);
54.}
该脚本的作用,就是每隔5秒,向日志文件中写入一个时间戳,当然,这个只是一个简单的示例,具体应用中,我们还需要根据业务的不同,编写具体的业务处理代码。
2. 以后台方式运行php脚本
在命令行下,输入:
1.nohup php /usr/local/src/daemon.php &
3. 查看日志输出
在命令行下,输入:
1.tail -f /usr/local/src/log.txt
我们将会看到如下信息:
4. 关闭php后台进程
首先,我们需要查出该进程的PID,命令:
1.ps -ef | grep "php /usr/local/src/daemon.php"
然后,通过这个PID把该进程kill掉
1.kill -9 22767
其中,22767就是php后台进程的PID号。
5. 开机自启
通过前面的步骤,我们知道如何开启和关闭一个php进程,但是,在实际的应用中,我们不可能每次都是手动开启,这样我们就会损失掉一部分业务数据,所以我们必须要让该进程开机自动运行,步骤如下:
在/etc/rc.local文件中,将nohupphp /usr/local/src/daemon.php&这个命令加入即可。