php stream_socket_client 第一次通话时间太长
php stream_socket_client first call takes too long
我正在通过 stream_socket_client()
打开多个 (75) 流,然后使用 stream_select()
对其进行处理。此方法的第一次调用大约需要。 15 秒,我不知道为什么。下一次调用要快得多——整个方法不到一两秒。我已将问题追踪到连接打开的 foreach,这本身需要 14/15 秒。
代码:
foreach ($tlds as $index => $server ) {
$ip = gethostbyname($server);
$con = @stream_socket_client($ip.':43',$errno, $errstr, 10, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT);
usleep(200);
if (!$con) {
$fails[] = $server;
} else {
$calls[$index] = $con;
stream_set_blocking($calls[$index], false);
}
//get time here
}
测试结果:
╔════════╦══════════╦══════════╗
║ $index ║ 1st call ║ 2nd call ║
╠════════╬══════════╬══════════╣
║ 0 ║ 5s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 10 ║ 6s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 20 ║ 7s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 30 ║ 9s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 40 ║ 11s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 50 ║ 12s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 60 ║ 13s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 70 ║ 14s ║ 1s ║
╠════════╬══════════╬══════════╣
║ end ║ 14s ║ 1s ║
╚════════╩══════════╩══════════╝
我完全没有套接字编程经验,所以非常感谢您提供任何提示。
PHP 7.1, Apache/2.4.6 (CentOS)
询问您需要的任何信息 - 希望我能够回答。
注意:有时第二次调用仍然花费第一次调用所用时间的 1/3 左右。但是下一个调用大约是 1 秒甚至更短。
我认为您遇到了 DNS 延迟问题。您可以在 linux 中尝试在循环中控制它以检测它。
time nslookup $server
如果确认dns速度慢,可以使用NSCD服务进行本地记录缓存。
在 CENTOS 中:yum -y install nscd;systemctl enable nscd;systemctl start nscd;
并重启 httpd 服务后。来自 nscd 的统计数据:/usr/sbin/nscd -g
我正在通过 stream_socket_client()
打开多个 (75) 流,然后使用 stream_select()
对其进行处理。此方法的第一次调用大约需要。 15 秒,我不知道为什么。下一次调用要快得多——整个方法不到一两秒。我已将问题追踪到连接打开的 foreach,这本身需要 14/15 秒。
代码:
foreach ($tlds as $index => $server ) {
$ip = gethostbyname($server);
$con = @stream_socket_client($ip.':43',$errno, $errstr, 10, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT);
usleep(200);
if (!$con) {
$fails[] = $server;
} else {
$calls[$index] = $con;
stream_set_blocking($calls[$index], false);
}
//get time here
}
测试结果:
╔════════╦══════════╦══════════╗
║ $index ║ 1st call ║ 2nd call ║
╠════════╬══════════╬══════════╣
║ 0 ║ 5s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 10 ║ 6s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 20 ║ 7s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 30 ║ 9s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 40 ║ 11s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 50 ║ 12s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 60 ║ 13s ║ 0s ║
╠════════╬══════════╬══════════╣
║ 70 ║ 14s ║ 1s ║
╠════════╬══════════╬══════════╣
║ end ║ 14s ║ 1s ║
╚════════╩══════════╩══════════╝
我完全没有套接字编程经验,所以非常感谢您提供任何提示。
PHP 7.1, Apache/2.4.6 (CentOS)
询问您需要的任何信息 - 希望我能够回答。
注意:有时第二次调用仍然花费第一次调用所用时间的 1/3 左右。但是下一个调用大约是 1 秒甚至更短。
我认为您遇到了 DNS 延迟问题。您可以在 linux 中尝试在循环中控制它以检测它。
time nslookup $server
如果确认dns速度慢,可以使用NSCD服务进行本地记录缓存。
在 CENTOS 中:yum -y install nscd;systemctl enable nscd;systemctl start nscd;
并重启 httpd 服务后。来自 nscd 的统计数据:/usr/sbin/nscd -g