如何将PHP内置服务器用作守护进程。

28 浏览
0 Comments

如何将PHP内置服务器用作守护进程。

我需要将一个php脚本作为守护进程运行(等待指令并执行任务)。cron任务无法满足我的需求,因为指令到达时需要立即采取行动。我知道由于内存管理问题,PHP并不是守护进程的最佳选择,但由于各种原因,我必须在这种情况下使用PHP。我发现了一个名为Daemon的libslack工具(http://libslack.org/daemon),它似乎可以帮助我管理守护进程,但在过去的5年里没有任何更新,所以我想知道您是否了解适合我情况的其他替代方案。非常感谢您提供的任何信息。

0
0 Comments

如何将PHP内置服务器用作守护进程

使用新的systemd,您可以创建一个服务。

必须在/etc/systemd/system/中创建一个文件或符号链接,例如myphpdaemon.service,并放置以下内容,myphpdaemon将是服务的名称:

[Unit]
Description=My PHP Daemon Service
#May your script needs MySQL or other services to run, eg. MySQL Memcached
Requires=mysqld.service memcached.service 
After=mysqld.service memcached.service
[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/myphpdaemon.pid
ExecStart=/usr/bin/php -f /srv/www/myphpdaemon.php arg1 arg2> /dev/null 2>/dev/null
#ExecStop=/bin/kill -HUP $MAINPID #It's the default you can change whats happens on stop command
#ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
StandardOutput=null #If you don't want to make toms of logs you can set it null if you sent a file or some other options it will send all PHP output to this one.
StandardError=/var/log/myphpdaemon.log
[Install]
WantedBy=default.target

您可以使用以下命令启动、获取状态、重新启动和停止服务:

systemctl  myphpdaemon

您可以使用PHP原生服务器使用`php -S 127.0.0.1:`或将其作为脚本运行。使用PHP脚本,您应该有一种“永远循环”的方式来继续运行。


工作示例:

[Unit]
Description=PHP APP Sync Service
Requires=mysqld.service memcached.service
After=mysqld.service memcached.service
[Service]
User=root
Type=simple
TimeoutSec=0
PIDFile=/var/run/php_app_sync.pid
ExecStart=/bin/sh -c '/usr/bin/php -f /var/www/app/private/server/cron/app_sync.php  2>&1 > /var/log/app_sync.log'
KillMode=mixed
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=default.target

如果您的PHP例程应该在一个周期内执行一次(例如摘要),则可以使用shell或bash脚本来调用systemd服务文件,而不是直接使用PHP,例如:

#!/usr/bin/env bash
script_path="/app/services/"
while [ : ]
do
#    clear
    php -f "$script_path${1}".php fixedparameter ${2}  > /dev/null 2>/dev/null
    sleep 1
done

如果您选择这些选项,则应将KillMode更改为混合模式以便杀死进程,bash(主进程)和PHP(子进程)。

ExecStart=/app/phpservice/runner.sh phpfile parameter  > /dev/null 2>/dev/null
KillMode=process

此方法也适用于解决内存泄漏问题。

注意:每次更改"myphpdaemon.service"时,必须运行`systemctl daemon-reload`,但如果您没有运行,系统将在需要时提醒您。

被低估的答案。我点赞。

太棒了。希望我们也可以为答案点赞,因为它不应该埋没在这个页面上。

嘿,我试图执行systemctl stop servicename,但php文件仍然输出到文件..我正在使用"working example"文件。

也许您启用了PHP中的忽略用户中止。

嗨,谢谢您的提示,但是服务仍然无法停止。我完全复制了php代码,并且当我运行ps -ef | grep php时,得到的结果是:user 14020 1 0 13:03 ? 00:00:00 /bin/sh -c /usr/bin/php -f /app/folder/test.php 2>&1 > /app/folder/log.out user 14021 14020 0 13:03 ? 00:00:00 /usr/bin/php -f /app/folder/test.php 我对pid控制器做的唯一更改是将用户和组设置为某个值。当然,我首先尝试了root,没有任何区别。

您应该检查`systemctl status -l`输出,它会给您提示发生了什么。

将此答案用于Ubuntu/Debian和/或2018+。

对于Ubuntu,mysqld是mysql,而且必须在安装memcache之前安装。此外,更实用的是使用符号链接到类似/var/www/daemons/myservice.service的东西。

MySQL和Memcached只是演示了如何使用服务依赖项,这是不必要的。

我在PHP中使用mysqli,不需要mysql服务引用吗?

您应该引用PHP服务器依赖的任何服务,以防止失败,但这并非必需。

感谢您的帮助。如何将其设置为自动启动?

`systemctl enable phpdaemon.service`

我有一些问题无法停止守护进程,即使使用了execStop,php也会无限运行,无法停止,多个脚本将同时运行,出现并发问题。

如果您的服务启动子脚本,应尝试其他配置的KillMode和ExecStop freedesktop.org/software/systemd/man/systemd.kill.html

鉴于现在是2019年,这应该真正替代被接受的答案。

我很惊讶为什么这不是被接受的答案...截至2020年最佳解决方案

sudo yum install -y supervisor 使用`systemd`

如果使用`Type=simple`,则不需要`PIDFile=`。 freedesktop.org/software/systemd/man/…

是否可以将此解决方案用于多线程作业?

当然可以,使用`pcntl_fork`

对于运行systemd的Linux系统,我认为这是最佳答案。我为此点赞。

一个问题,为什么选择一个随机数来调用gc?假设rand是以大约20次迭代为种子,将调用gc_collect_cycles()。是一些明显的波动,但接近。我会建议使用计数器来监视脚本,并根据您的需求使用gc来调用,例如`if(($counter++ % 20) == 0)`,然后进行调整。

0
0 Comments

如何使用PHP内置服务器作为守护进程

在命令行(如bash)中,可以通过以下方式启动PHP脚本:

nohup php myscript.php &

&将进程放在后台运行。

是的,这种方法存在一些缺点,但无法控制是错误的。

一个简单的kill processid命令将停止它。这仍然是最好和最简单的解决方法。

如果终端退出,进程不会结束。这就是为什么要使用"nohup"命令的原因。多年来,我一直在所有服务器上使用这种方式将PHP脚本作为守护进程运行。可能有更好的解决方法,但这是最快捷的方法。

这种方法不会在守护进程失败时重新启动它,也没有简单的方法来管理守护进程。

我同意这里说的话-这是一个糟糕的解决方法。你应该创建一个初始化脚本,原因有几个:1)初始化脚本在启动时自动启动2)你可以使用启动/停止/重启命令来管理守护进程。以下是来自servefault的一个例子:serverfault.com/questions/229759/…

嘿伙计们...在我看来,nohup&做的事情是一样的:将启动的进程与当前shell实例分离。为什么我需要同时使用它们?我不能只做php myscript.php &nohup myscript.php吗?谢谢

为了更清晰地解释这个问题。nohup会让脚本忽略SIGTERM信号,但显然仍会在收到KILL信号时终止。你需要同时使用nohup&nohup会确保如果父进程死亡,脚本不会随之死亡,&会确保脚本被立即推到后台运行。简而言之,这是一种不错但有点hacky的守护进程方法,在PHP中,对于这种用例,你几乎完全依赖于hacky的方法。

如果脚本通过echo或var_dump写入stdout,则可以使用以下命令将这些信息捕获到日志文件中:nohup php myscript.php > myscript.log &

-1:这里的建议很糟糕,会导致进程没有正确与控制终端隔离,并产生僵尸进程。

0
0 Comments

如何将PHP内置服务器用作守护进程

在使用PHP内置服务器作为守护进程时,有时会遇到问题。下面是问题出现的原因和解决方法:

问题原因:

- 使用/etc/init/myphpworker.conf脚本文件时,如果PHP脚本返回字符串"ERROR",守护进程会停止运行。

- 使用sudo service myphpworker start命令启动守护进程时,可能会出现myphpworker: unrecognized service错误,因为这个命令只适用于在/etc/init.d目录下的服务,而不是upstart服务。

- 在脚本中如何传递参数?

解决方法:

- 创建一个新的脚本文件,在/etc/init/myphpworker.conf路径下,用于启动和管理守护进程。

- 在脚本文件中设置启动和停止事件,以及自动重启守护进程的配置。

- 使用sudo service myphpworker start/stop/status命令来启动、停止和检查守护进程的状态。

下面是一个使用Upstart作为守护进程的例子:

# Info
description "My PHP Worker"
author      "Jonathan"
# Events
start on startup
stop on shutdown
# Automatically respawn
respawn
respawn limit 20 5
# Run the script!
# Note, in this example, if your PHP script returns
# the string "ERROR", the daemon will stop itself.
script
    [ $(exec /usr/bin/php -f /path/to/your/script.php) = 'ERROR' ] && ( stop; exit 1; )
end script

启动和停止守护进程的命令:

sudo service myphpworker start
sudo service myphpworker stop

检查守护进程是否正在运行:

sudo service myphpworker status

需要注意的是,Ubuntu正在逐渐转向使用systemd而不是Upstart作为守护进程管理器。

感谢Kevin van Zonneveld的博客文章,我从中学到了这个技巧。

如果需要在启动时传递参数给脚本,可以使用以下方式:

exec /usr/bin/php -f /path/to/your/script.php SOME_PARAM1 SOME_PARAM2

这样,在守护进程自动重启时,会使用相同的参数。

通过使用Upstart作为守护进程管理器,我们可以轻松地将PHP内置服务器作为守护进程运行,并在系统启动时自动启动它。同时,我们还可以通过设置脚本文件来控制守护进程的行为,例如自动重启和停止条件。如果需要传递参数给脚本,可以在启动命令中指定参数。

0