lifo / php-daemon
PHP 多进程守护进程
Requires
- php: >=7.4
- ext-pcntl: *
- ext-sysvmsg: *
- ext-sysvsem: *
- ext-sysvshm: *
- symfony/event-dispatcher: ^4.4||^5.0||^6.0
- symfony/process: ^4.4||^5.0||^6.0
Suggests
- symfony/options-resolver: For better plugin options support
- symfony/var-dumper: For better debug dump output
README
概要
创建没有样板代码的强大且稳定的 PHP 多进程守护进程。核心 守护进程 类处理主循环和事件,并且可以以所需的任何频率运行 (在 PHP 限制范围内)。您只需实现一个方法 execute
来运行守护进程,可选地在后台运行。
使用 任务 和 工作进程,守护进程可以无缝地在后台进程中调用方法,无需担心管理分叉的子进程。 插件 允许您轻松地为您守护进程创建可重用和可共享的代码。有关更多信息,请参阅下面的 功能 部分。
为什么用 PHP 编写守护进程?
显然,在 PHP 中编写健壮、稳定且长期运行的守护进程通常不是一个好主意。至少很难做到,也很难做好。我之所以需要用 PHP 编写守护进程,是因为我有一个用 Symfony 构建的整个网站框架,需要一个主要的后端守护进程。我想能够重用所有前端依赖项和实体,而无需复制资源或配置。
虽然这个库尽可能地允许您创建一个坚不可摧的守护进程,但在您的用户代码中仍需注意保持稳定性。
需求
文档
有关文档,请参阅 Wiki。
示例
请参阅 示例 目录中的示例。
功能
- 主循环由核心 守护进程 类维护。您只需实现一个方法
execute
,该方法将在每个循环周期被调用。循环频率可以是秒的任何分数值。如果设置为 0,则execute
方法将尽可能快地被调用(通常不推荐,除非您的循环正在执行某种阻塞调用,例如:监听套接字等)。 - 只需几行代码,您就可以在后台运行并行进程。
-
任务允许您在后台进程中调用任何方法或回调。后台进程与父进程之间没有通信。任务适用于简单的事情,例如:发送电子邮件。
-
工作进程允许您调用对象上的任何方法,甚至只是一个简单的回调,例如任务。工作进程可以通过在您的工人方法中简单使用
return
语句来将值返回给父进程。工作进程会自动维护,并且可以同时运行多个子进程,这是透明处理的。即使工作进程死亡或被操作系统杀死,Daemon API仍然会返回结果(或异常)到您的代码。工作进程的返回值通常是Promise
对象。您可以使用标准的Promise方法,如then
或otherwise
来处理返回值。或者,您可以在Worker上注册一个ON_RETURN
回调。工作进程使用中介设计模式,并使用共享内存作为它的消息队列和数据。可以创建不同的IPC类来提供父进程和子进程之间的替代通信方法。我可能会开发一个使用套接字而不是SHM的第二个IPC类,以提供另一种选择。
-
- 事件处理。核心
Daemon
有几个事件(见:事件),您可以通过注册一个回调轻松地与它们接口。一些事件可以改变守护进程的行为。 - 通过事件调度器简单处理信号。要捕获一个信号,您只需在您的代码中注册一个
ON_SIGNAL
回调。您的回调将接收到一个包含捕获信号的SignalEvent
。 - 简单的
Plugin
架构允许您使用和创建自己的插件,这些插件可以被注入到守护进程。插件可以延迟加载。- 核心插件
FileLock
允许您添加一个锁定机制,以防止守护进程同时运行多个实例。只需在您的守护进程中注册插件,其余的就会自动完成。一个ShmLock
类似,但它使用共享内存来获取锁。
- 核心插件
- 自动重启。如果守护进程的运行时间达到可配置的阈值或发生致命错误,守护进程可以自动重启。
- 内置日志记录。
Daemon
有3个基本的日志方法:log
、error
、debug
。所有这些都会写入日志文件(如果已配置)。如果日志文件被轮换、覆盖或删除,守护进程会自动检测到这一点,并继续写入新的日志文件。DaemonEvent::ON_LOG事件允许您注册一个回调来更改行为。用户代码可以使用LogTrait轻松地将本地守护进程日志添加到他们的代码中。
致谢
此库的基础灵感来源于GitHub上PHP-Daemon库,作者是Shane Harter。不幸的是,他的库已被放弃(或处于无限期暂停),为PHP v5.3编写,没有命名空间、没有包管理或自动加载器(即:Composer)。
我选择创建一个全新的库,而不是为了教育目的对原始库进行分支和修改。我还不同意他的某些方法。我确实需要一些额外的依赖,但Composer使这个问题变得微不足道。
此库处于完全工作状态。我已经创建了一些非常复杂的守护进程,它们已经运行了几个月,没有任何内存泄漏或崩溃。还可以做更多...