问题: 我的网站上有一个页面,该页面使用cURL向本地主机上的另一个资源发出请求。如果发出的并发请求数量超过子进程php-fpm的数量,则服务器将冻结直到所有请求超时。在冻结状态下,查看顶部显示所有php-fpm处理器都在休眠。仅当cURL在相同或不同虚拟主机上的本地主机上请求资源时,才会出现此问题,因此似乎发生了某种类型的锁定?
下面是一个使用cURL调用另一个页面的页面示例:
serverOne.php
<div style='position:fixed;overflow:none;height:100%;bottom:0;width:100%;top:0;display:table;text-align:center;background:hsla(0,0%,0.72)' id='passward-protected'>
<div style='display:table-cell;vertical-align:middle'>
This Page is password protected
<button onclick='enterpass()'>Enter Password</button>
</div>
</div>
<!-- paste this password form in your blogger post/page -->
<script language="JavaScript">
function enterpass(){
var password = ' '
password=prompt('This is password protected page,please enter password to continue.','');
if (password == 'password') {
document.getElementById('passward-protected').style.display='none';
}else{
alert('Wrong Password')
}
}
</script>
所有请求最终都因504网关超时而超时,服务器再次变得响应。
预期的行为: 服务器应该轻松处理比此更多的请求,但是在有25个以上的请求时冻结(这是pm.max_children设置的)。其他任何页面都可以处理数千个请求。
我创建了一个存储库,以最小化复制从mod_php到php-fpm的php应用程序后遇到的并发问题。 https://github.com/paul-rchds/php-fpm-curl-issue
复制问题。请克隆链接的存储库并运行:
<?php
$ch = curl_init();
curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt($ch,CURLOPT_URL,"http://127.0.0.1/serverTwo.php");
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
运行运行并发连接的python脚本:
docker-compose up --build
python脚本将向页面serverOne.php发出50个并发请求,此页面向serverTwo.php发出卷曲请求。如您所见,服务器将冻结直到超时。更改python脚本URL以直接向serverTwo.php请求,您可以轻松地将请求数量增加到1000 +,而不会发生任何超时。