3

在 CakePHP 中,有各种用于管理队列本身的系统(RabbitMQbeantalkAmazon SQSdereuromark 的 cakephp-queue),但所有这些似乎都需要一个守护进程的工作任务。这些永远在线的工作人员(背后拥有 CakePHP 的全部功能)在作业进入队列时监听它们,进行处理,然后闲置直到下一个作业出现。

目前,我正在使用基于 beanstalk 的队列(上面链接),它工作正常,但就服务器资源而言,它并不是特别有效。我们有内存泄漏,有时不得不终止并重新启动进程。

但是,现在我正在尝试添加更多不同类型的“管”(用 beanstalk 的说法),并且我在同时运行这么多不同工作人员的服务器上遇到了 RAM 问题。当我启动我想要的所有不同的工人时,我会遇到致命的内存不足错误。

我宁愿有类似“无服务器”/Lambda 风格的设置,其中工作人员按需启动,完成它的小工作,然后自行终止。有点像调用 CakePHP shell 的 cron 作业,但作业数据是从队列中动态填充的。

有没有人有这种排队设置的经验?我在一个基于 AWS 的基础设施上,所以任何使用亚马逊服务的东西都会特别有用。

4

1 回答 1

1

据我所知,只有两种方法可以运行 PHP。作为 Web 容器(Apache、Nginx、CGI)内的线程或作为 shell 进程(单线程)。当你在 shell 上运行它时,你会被困在每个进程 1 个线程上。

我知道这很糟糕,但 PHP 并不是服务器工作者的最佳工具。Lambda架构不会真正帮助解决这个问题。您刚刚将多线程问题加载到另一台主机。

归根结底,最简单的解决方案是运行更多 PHP 进程。如果你遇到崩溃。您需要在 shell 脚本中运行 PHP。这只是命令行中 PHP 的特性。

但是,我会根据我的经验分享您还有哪些其他选择。

但是,现在我正在尝试添加更多不同类型的“管”(用 beanstalk 的说法),并且我在同时运行这么多不同工作人员的服务器上遇到了 RAM 问题。当我启动我想要的所有不同的工人时,我会遇到致命的内存不足错误。

上次我检查 beanstalk 是单线程的。所以我认为 PHP 不可能用 beanstalk 一次产生多个工人。您必须运行 1 个 PHP 实例,该实例会收到一条消息并对其进行处理。如果要扩展,则必须运行多个 PHP 实例。

听起来您的工作人员要么有内存泄漏,要么只是消耗了大量内存。我不明白这与豆茎有什么关系。您必须修复泄漏并更改源代码以使用更少的内存。

我不得不重写 PHP 代码以使用正向 XML 解析器,因为另一个 XML 解析器会将整个文档加载到内存中。正读解析器使用较少的内存,但是重写我的所有代码很痛苦。你必须决定哪个花费你更多。在 Ram 上花更多的钱或花时间重写代码。那是你的电话。

记忆

PHP 带有对内存使用的软限制。即使主机有大量内存,PHP 线程在达到软限制时也会抛出内存不足错误。这是您必须在php.ini文件中手动更改的内容。如果你已经这样做了,请原谅我,但我认为值得一提。

增加 PHP 内存限制php.ini

memory_limit = 128M

一次性图案

我使用一次性模式解决了很多内存泄漏问题。这只是interface您在对象上使用的简单方法,然后将代码包装在using()函数中。使用这个库,我能够将内存泄漏减少 99%。(完全披露,这是我的 github 库)。

https://github.com/cgTag/php-disposable

多线程 PHP

有一个开源项目为 PHP 添加了多线程支持,在我看来它就像一个可靠的库。

https://github.com/krakjoe/pthreads

该项目为 PHP(使用 C++ 模块)添加了多线程支持,基本上为每个线程创建了一个新的全局范围。这允许您在每个线程中运行一个 CakePHP shell,我认为有一个用于线程间数据共享的 API(互斥锁和类似的东西)。

码头化

我在运行 docker 以处理单个 CakePHP shell 任务方面取得了一些成功。这使我能够通过在同一主机上运行多个容器来快速扩展。容器的额外内存开销确实没有那么糟糕。我不记得确切的数字,但它比你想象的要少。

守护进程

它们是在 Linux 上运行服务的久经考验的方式。这里唯一的问题是每个守护程序在 PHP 中有 1 个线程。所以你必须注册多个守护进程才能扩大规模。话虽如此,这个选项适用于上面的多线程库。

于 2018-01-26T03:16:46.953 回答