phpcakephpphp-7.1stream-socket-client

php stream_socket_client first call takes too long


I'm opening multiple (75) streams through stream_socket_client() and then processing it with stream_select(). The first call of this method takes approx. 15 seconds and I have no idea why. Next calls are much faster - less than one or two seconds for whole method. I've tracked the issue to the foreach where connections are getting opened, which takes 14/15 seconds itself.

Code:

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
}

Testing results:

╔════════╦══════════╦══════════╗
║ $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       ║
╚════════╩══════════╩══════════╝

I'm not experienced in socket programming at all so I'm greatful for any hints.

PHP 7.1, Apache/2.4.6 (CentOS)

Ask for any info you need - hope I'll be able to answer.

Note: Sometimes the second call still takes around 1/3 of the time the first call takes. But next calls are around 1 second or even less.


Solution

  • I'm thinking that you have problem with DNS latency. You can try in linux console this in loop to detect it.

    time nslookup $server
    

    If you confirm that dns is slow, you can use NSCD service for local cache of records. In CENTOS : yum -y install nscd;systemctl enable nscd;systemctl start nscd; and after restart httpd service. Statistics from nscd: /usr/sbin/nscd -g