2

我有一个我无法处理的奇怪问题。我不知道该怎么做,我已经将 php.ini 设置为以下内容:

max_execution_time = 120
memory_limit = 1024M
output_buffering = on
compression is turned off

网络服务器在大约 95% 时处于空闲状态,并且有 6GB 的可用内存。

我还调整了 apache MPM:

mpm_prefork_module:
StartServers          500
MinSpareServers       500
MaxSpareServers      1000
MaxClients          5500
MaxRequestsPerChild   0

但这一切都无济于事(我也尝试了不同的值)。

我需要每分钟处理大约 3000 个传入的 API 请求。我需要为每个返回大约 50KB。

服务器可以处理该数量的传入请求。我测试了它。它只是不能把所有的数据都扔掉。有一种节流。但是在测试带宽时,我得到了完整的 100MBit。

这是我的问题:

当我通过 apache2 下载静态二进制文件时,我的速度为 12000 KiloByte/sec,所以这几乎是整个 100MBit 连接。

我创建了一个 php 文件,它执行所有 API 内容,但不返回结果。它只是返回一些特定大小的随机数据。现在我正在从不同的服务器加载具有许多线程(当时为 1000 个)的文件/数据。

现在我检查了服务器每分钟处理多少个请求。我计算了每秒的传输速率。

      0 byte = about 5000
   1000 byte = about 3000 =  50 Kilobyte/sec
  10000 byte = about 1600 = 266 Kilobyte/sec
  50000 byte = about  430 = 358 Kilobyte/sec
 100000 byte = about  337 = 561 Kilobyte/sec
 500000 byte = about   69 = 567 Kilobyte/sec

这表明在不返回数据时,服务器可以处理所需数量的请求(它每分钟可以处理 5000 个,而不是我需要的 3000 个)。当我返回我需要的 50KB 时,我每分钟只收到 430 个请求。我返回随机数据还是真实数据都没有关系,使用真实的 PHP 文件或者只是一个返回一些随机 50KB 数据的虚拟数据。这没有任何区别。

我该怎么做才能解决 php 节流问题?

以下是一些会导致相同限制问题的源代码:

<?
$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

for ($i = 0; $i < 50000; $i++) 
{
  echo $chars[rand(0, strlen($chars))];
}
?>
4

1 回答 1

0

这里可能有几个因素在起作用:

PHP 的开销

即使对于只生成一个文件的基本脚本,PHP 也必须初始化它自己。这是有代价的。

内存开销

很有可能,您的 PHP 脚本导致将整个 50KB 的数据复制到内存中(这也是成本)。除非您跳过箍以流式传输结果,否则这很可能会发生。

缓冲

与上面类似,如果您没有对结果进行流式处理/分块 - PHP 必须先将整个数据块加载到内存中,然后再将其发送给请求者。

未知数

PHP 的内部有很多变化的部分,如果不剖析和分析您的特定脚本,就对减速的真正位置做出许多假设可能是不安全的。

解决它

像 apache 和 nginx 这样的 Web 服务器已针对提供静态文件进行了很好的优化。让他们这样做;它们总是比在它们之间引入一层间接更快。

我对您的具体问题知之甚少,但一般准则:

  • 让 PHP 脚本进行基本处理,然后重定向到您的 Web 服务器直接提供的 URL。
  • 如果您需要安全层;考虑设置一次性 URL 或服务器模块,可以快速检查请求者是否具有访问权限(但不必管理 w/ 流文件内容)
于 2013-01-20T23:02:29.327 回答