4

我有个问题。我拥有一个 128mb vps 的简单博客,每天只有 100 次点击。我安装了 nginx + php5-fpm。考虑到低访问量和内存,我决定将 fpm 设置为静态并运行 1 个服务器。当我进行随机测试(例如通过 http 运行 php 脚本持续 30 多分钟)时,我尝试在同一台机器上打开博客,发现该站点基本上无法访问。所以我去配置并阅读:

     The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes to be created when pm is set to 'dynamic'.
; **This value sets the limit on the number of simultaneous requests that will be
; served**

最让我震惊的是我不知道,因为我一直认为一个 php 子进程会像 http 服务器一样同时处理数百个请求!做对了吗?例如,如果我同时启动 2 个 php-fpm 子进程并启动 2 个“长脚本”,那么所有使用相同 php 后端的站点都将无法访问??这个怎么用?你可能会想:-duh!一个 php 脚本(网页)通常在 100 毫秒内处理-...毫无疑问,但是如果您的页面每个可以运行大约 10 秒,并且我有 10 个使用 php-fpm 的访问者和 5 个服务器所以只接受每次5个请求同时?他们都将排队或​​将经历超时?

老实说,我习惯于在 Windows 中使用 Apache 和 mod_php 运行站点,我从未遇到过这些问题,因为显然这些限制不适用于使用 PHP 的不同方式。

这也提出了另一个问题。如果我有带有 sleep(20) 的 file_1.php 和带有 echo 的 file_2.php,如果我使用 fastcgi 机器运行 file_1 然后 file_2 第二个文件将请求创建另一个服务器来处理使用 4MB RAM 更多的 php 请求. 如果我对 apache/mod_php 做同样的事情,第二个文件将只使用 30KB 以上的 RAM(在 apache 服务器中)。考虑到这一点,如果使用的 ram 实际上更少,为什么 mod_php 会考虑“坏人”……我知道我在这里错过了大局。

4

1 回答 1

19

你基本上是对的。你配置了一个静态的工人数量(这个数字是“一个”)——这正是你得到的。

但是您不太了解事情通常是如何工作的,因为您说:

我一直认为 php 子进程会像 http 服务器一样同时处理数百个请求!

我对 nginx 不是很熟悉,但考虑一下 apache 中典型的 mod_php 设置。如果您使用的是 mod_php,那么您使用的是 prefork mpm for apache。因此,每个并发的 http 请求都由不同的 httpd 进程(无线程)处理。如果您正在为低内存调整 apache/mod_php 服务器,您将不得不调整 apache 设置以限制它将产生的进程数(特别是 MaxClients)。

未能调整这些东西意味着当您遇到大量流量峰值时,apache 开始产生大量繁重的进程(请记住,它是 mod_php,因此您在每个 httpd 进程中嵌入了整个 PHP 解释器),并且您的内存不足,然后一切都开始交换,您的服务器开始冒烟。

调整得当(意思是:调整得让你忽略请求,而不是为更多进程分配你没有的内存),客户端会超时,但是当流量减少时,事情就会恢复正常。

将其与 fpm 以及更智能的 Web 服务器架构(如 apache-worker 或 nginx)进行比较。现在你有一些更大的线程池(仍然是可配置的!)来处理 http 请求,以及一个单独的 php-fpm 进程池来处理需要 PHP 的请求。基本上是一样的,如果你不限制可以创建多少个进程/线程,你就是在自找麻烦。但是,如果您进行了调优,您就会领先一步,因为您的请求中只有一小部分使用 PHP。因此,从本质上讲,每个 http 请求所需的平均内存量较低——因此您可以使用相同的内存量处理更多请求。

但是将数字设置为“1”太极端了。在“1”处,您选择静态还是动态都没有关系,因为无论哪种方式,您都只有一个 php-fpm 进程。

因此,要尝试对特定问题给出明确的答案:

你可能会想:-duh!一个 php 脚本(网页)通常在 100 毫秒内处理-...毫无疑问,但是如果您的页面每个可以运行大约 10 秒,而我有 10 个使用 php-fpm 的访问者和 5 个服务器,所以只接受每次5个请求同时?他们都将排队或​​将经历超时?

是的,他们都会排队,最终超时。但是,您经常需要 10 秒才能运行脚本这一事实是真正的罪魁祸首。有很多方法可以解决这个问题(缓存、工作队列等),但正确的解决方案完全取决于你想要做什么。

老实说,我习惯于使用 Apache 和 mod_php 在 Windows 中运行站点我从未遇到过这些问题,因为显然这些限制不适用于使用 PHP 的不同方式。

他们确实适用。您可以像使用 nginx/php-fpm 一样设置 apache/mod_php 服务器——只需将 apache 的 MaxClients 设置为 1!

这也提出了另一个问题。如果我有带有 sleep(20) 的 file_1.php 和只有 echo 的 file_2.php,如果我使用 fastcgi 机器运行 file_1 然后 file_2 第二个文件将请求创建另一个服务器来处理使用 4MB RAM 以上的 php 请求. 如果我对 apache/mod_php 做同样的事情,第二个文件将只使用 30KB 以上的 RAM(在 apache 服务器中)。考虑到这一点,如果使用的 ram 实际上更少,为什么 mod_php 会考虑“坏人”……我知道我在这里错过了大局。

尤其是在 linux 上,许多报告内存使用情况的东西可能会非常具有误导性。但是这样想:30kb 可以忽略不计。那是因为当一些 httpd 进程启动时,大部分 PHP 的内存已经被分配了。

128MB VPS 相当紧张,但应该能够处理多个 php 进程。

如果要优化,请执行以下操作:

对于 PHP:

pm = static
pm.max_children=4

对于 nginx,弄清楚如何控制进程和线程数(无论是 apache 的 MaxClients、StartServers、MinSpareServers、MaxSpareServers 的等价物)

然后弄清楚如何生成一些真实的负载(apachebench、siege、jmeter 等)。使用vmstatfreetop来查看您的内存使用情况。将 pm.max_children 和 nginx 的东西调整到尽可能高而不引起任何重大交换(根据vmstat

于 2012-05-21T01:54:56.643 回答