首页 > 解决方案 > PHP 将来自同一来源的传入 CURL 请求分开处理

问题描述

我有 website1 和 website2,每个网站都有自己的网络服务器,每个网站都使用最新版本的 Apache MPM 和 PHP。

来自 website1 的访问者向 website1 发送 POST 请求,然后 website1 通过 cURL 与 website2 通信并将一些数据传递给它,然后等待响应。

网站1代码示例:

$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,'https://www.website.com?request='.$enc_data);

curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT_MS ,30000); 
curl_setopt($ch,CURLOPT_TIMEOUT_MS, 30000); //timeout in seconds

$result = curl_exec($ch);   
//log the result to database
curl_close($ch);

网站 2 执行一些需要大约 1 秒才能执行的操作。所以每次响应时间都超过1秒。有时甚至是2-3秒。

website2 的示例代码(用于模拟目的)

sleep(mt_rand(1,3)); 
echo 'Request solved';

问题是,如果 100 个请求通过上面的代码从 website1 到 website2,它们会被一个一个地执行(FIFO)而不是并行执行。这意味着在第 30 个请求之后,一切都超时。

问题是这些请求是不断完成的,它们的数量会增加,我需要 website2 能够以某种方式并行处理它们。我不能接受连续的超时。服务器可以升级以获得更多资源,这不是问题。

就像在任何动态服务器上一样,如果 100 人从他们的浏览器向 website1 发送请求(通过单击按钮或刷新网站),那么该请求将由 website1 单独处理,而不会在其他 99 个人中的任何人访问时增加延迟来自 website1 的任何页面,因为我假设 Apache 将每个请求分配给一个线程/工作者。

我希望 website2 处理来自 website1 的请求,基本上将每个请求作为不同的“请求者”处理并并行处理。

我假设这可能是 apache 设置或我需要添加到 cURL 请求中的标头的东西,以便 website2 认为请求来自不同的 IP/访问者或类似的东西。

任何人都可以指导我如何实现我所需要的吗?

标签: phpmultithreadingcurlmultiprocessingphp-curl

解决方案


关于问题:

问题是,如果 100 个请求通过上面的代码从 website1 到 website2,它们会被一个一个地执行(FIFO)而不是并行执行。这意味着在第 30 个请求之后,一切都超时。

如果在 server2 上运行 apache,那么为什么 website2 应该一个一个地执行而不是并行呢?cURL 访问 website2 的方式与浏览器相同。

请求被一一执行绝对不是真的。

阿帕奇:

Apache 提供了一个标准配置,这个配置不包含这么小的限制。但是,您可以增加设置:

    StartServers              5
    MinSpareServers           5
    MaxSpareServers          10
    MaxRequestWorkers         150
    MaxConnectionsPerChild   0

有关此的更多信息-也许这可以帮助您: https ://serverfault.com/questions/775855/how-to-configure-apache-workers-for-maximum-concurrency

在您的位置上,我还将关闭 Apache2 配置中的 Keepalive,以免浪费连接:

    KeepAlive Off

卷曲:

我什至会使用 CURL_OPT_HTTPHEADER 在 curl 站点上关闭 keepalive:

curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
    'Connection: Close'
));

并禁止 cURL 通过使用来重用连接 - i 它还应该有助于避免阻塞:

curl_setopt($curlHandle, CURLOPT_FORBID_REUSE, TRUE);

另一种设置是避免(有时发生)当 cURL 无法解析 ipv4 并重试解析 IPv6(未配置或错误)时的长时间等待。

curl_setopt($curlHandle,  CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);

还有许多其他选项可以调整您的速度。将数据从一台服务器发送到另一台服务器通常不是一个很好的解决方案,它延长脚本的执行时间是绝对正常的。但是你收到超时是不正常的。如上所述调整您的设置,它应该可以解决它 - 问题更多的是在 Server2 Apache 配置上,而不是在 cURL 端。


推荐阅读