假设您正在编写一个为作业队列提供服务的守护进程.各种其他软件将守护程序的作业写入队列.守护程序每隔几秒轮询队列以查找挂起的作业.假设队列是作为MySQL数据库中的表实现的,并且守护进程是一个简单的循环:
守护程序必须经受MySQL数据库服务器的中断服务和数据库连接中断.
您是否会将守护进程设计为每个周期连接一次数据库服务器?即在1.之前连接并在2和3之间断开连接?
或者你有守护进程保持连接打开?在这种情况下,它还需要a)检测服务器或连接何时不工作,b)断开连接和重新连接,以及c)这样做而不累积数据库连接,哑连接描述符或其他死资源.
如果您有偏好,为什么?
优点和缺点?
进入设计的因素?
还有其他方法吗?
答案在这里:用PHP编写的守护进程的mysql连接并没有说为什么最好保持连接打开.我在别处读到MySQL中的每个连接开销非常轻.因此,为什么永久消耗一个服务器连接比每隔几秒连接/断开更好是不明显的.
在我的例子中,守护进程是用PHP编写的.
我实际上工作的东西非常接近你描述的东西,但在我的情况下,守护进程不会轮询事件,它通过XMPP异步获取它们(但除此之外).
切出中间人
我认为不是将事件存储在数据库中并使用MySQL进行轮询,而是可以使用Gearman异步地从客户端发送它们(例如).
垃圾收集
PHP并不是真正设计为作为守护进程运行的,直到PHP 5.3才获得循环引用垃圾收集它才成为可行的选择.这是非常,如果你想在长期运行没有内存泄漏任何机会,你使用PHP 5.3重要.
关于GC要记住的另一件事是,如果内存不再被引用(任何地方),那么它只是免费的.因此,如果将变量分配给全局范围,它将一直存在,直到守护程序退出.重要的是,您创建或使用的任何代码都不会在某些位置构建变量(即静态日志,而不是删除旧数据等).
统计缓存
另一件事是clearstatcache经常跑步很重要.由于您的PHP进程未重新启动,因此手动执行此调用以防止获取旧的统计数据(可能会或可能不会影响您)非常重要.根据文档,这些函数被缓存.
受影响的函数包括stat(),lstat(),file_exists(),is_writable(),is_readable(),is_executable(),is_file(),is_dir(),is_link(),filectime(),fileatime(),filemtime() ,fileinode(),filegroup(),fileowner(),filesize(),filetype()和fileperms().
资源管理
如果你在进程的生命周期中使用像MySQL这样的东西,我建议你在启动时建立一个连接并使其保持活动状态.即使它可能在MySQL端使用更多ram,你也可以通过不必每1秒连接来减少一些延迟和CPU开销.
没有网址请求
这似乎很明显,但使用CLI PHP时,没有URL请求信息.有些库并没有考虑到这一点,这可能会导致一些问题.
LooPHP
我将在这里弹出一个无耻的插件,用于我编写的框架,以帮助管理PHP守护进程.LooPHP是一个运行循环框架,允许您安排事件发生或创建侦听抽象源(套接字,流等).在我的情况下,我让守护进程做了不止一件事,所以让系统跟踪我的所有计时器是非常有帮助的,这样我就可以有效地轮询stream_selectXMPP连接.