php - 如何设计一个带有 MySQL 数据库连接的守护进程

标签 php database daemon

<分区>

假设您正在编写一个为作业队列提供服务的守护进程。各种其他软件将守护进程的作业写入队列。守护进程每隔几秒轮询一次队列以查找挂起的作业。假设队列被实现为 MySQL 数据库中的一个表,并且守护进程是一个简单的循环:

  1. 从队列中获取所有到期的工作
  2. 做作业
  3. 休眠N秒
  4. 转到1

守护进程必须在 MySQL 数据库服务器中断的服务和数据库连接中断时存活下来。

您是否会将守护程序设计为每个周期连接一次数据库服务器?即在 1 之前连接并在 2 和 3 之间断开连接?

或者您会让守护进程保持连接打开吗?在这种情况下,它还需要 a) 检测服务器或连接何时不工作,b) 断开连接并重新连接,c) 在不累积数据库连接、无效连接描述符或其他死资源的情况下这样做。

如果您有偏好,为什么?

优缺点?

进入设计的因素?

还有其他方法吗?

答案在这里:mysql connection from daemon written in php没有说明为什么最好保持连接打开。我在别处读到,MySQL 中的每个连接开销非常小。因此,为什么永久使用一个服务器连接比每隔几秒连接/断开连接要好,这一点并不明显。

在我的例子中,守护进程是用 PHP 编写的。

最佳答案

我实际上正在研究 something与您描述的非常接近,但在我的例子中,守护进程不会轮询它通过 XMPP 异步获取的事件(但这不是重点)。

去掉中间人

我认为与其将事件存储在数据库中并使用 MySQL 轮询它们,不如使用 Gearman。从客户端异步发送它们(example)。

垃圾回收

PHP 并非真正设计为作为守护进程运行,直到 PHP 5.3 才获得 circular reference garbage collection。它成为一个可行的选择。如果您想长期运行而不会出现内存泄漏,那么使用 PHP 5.3 是非常重要的。

另一件关于 GC 需要牢记的事情是,内存只有在不再被引用(任何地方)时才是空闲的。因此,如果您将变量分配给全局范围,它将一直存在直到守护进程退出。重要的是,您创建或使用的任何代码都不会在某些地方建立变量(即静态日志、不删除旧数据等)。

统计缓存

另一件事是,经常运行 clearstatcache 很重要。由于您的 PHP 进程未重新启动,因此手动执行此调用非常重要,以防止获取旧的统计数据(这可能会或可能不会影响您)。根据documentation这些函数被缓存。

Affected functions include stat(), lstat(), file_exists(), is_writable(), is_readable(), is_executable(), is_file(), is_dir(), is_link(), filectime(), fileatime(), filemtime(), fileinode(), filegroup(), fileowner(), filesize(), filetype(), and fileperms().

资源管理

如果您打算在进程的生命周期内使用 MySQL 之类的东西,我建议在启动时建立一个连接并保持连接。尽管它可能会在 MySQL 端使用更多内存,但您不必每 1 秒连接一次,从而减少一些延迟和 CPU 开销。

没有 URL 请求

这看起来很明显,但是 CLI PHP 没有 URL 请求信息。有些库在编写时并未考虑到这一点,这可能会导致一些问题。

LooPHP

我要在这里插入一个无耻的插件,用于我编写的框架,以帮助管理 PHP 守护进程。 LooPHP是一个运行循环框架,可让您安排事件发生或创建抽象源(套接字、流等)的监听。在我的例子中,我让守护进程做不止一件事,所以让系统为我跟踪所有计时器非常有帮助,这样我就可以有效地为 XMPP 连接轮询 stream_select

关于php - 如何设计一个带有 MySQL 数据库连接的守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4169412/

相关文章:

php - 如何使用 CentOS 7 在 PHP 7.2 上安装 zipArchive?

php - 具有相同 html 的两个页面呈现不同的效果

SQLITE:如何对包含值 1-99 和字母 a-z 的字符串列进行排序,首先是数字,然后是字母

ruby - 唯一的一对两个整数

Python线程/守护进程

linux - 事件按钮作为模块还是作为用户程序?

php - 为什么我的哈希值总是全 0?

php - FFMPEG 脚本不在 php 中运行

python - 数据库游标

运行守护进程后找不到守护进程日志