A "Bug" _ PHP Tutorial on milliseconds timeout of PHPCurl

Source: Internet
Author: User
Tags sigalarm centos server
A "Bug" in milliseconds of PHPCurl timeout ". Recently, our service is upgrading the libcurl used by php. we expect the new version of libcurl to support millisecond-level timeout, so that we can more precisely control the backend interface timeout, in this way, the overall response is improved. our service is upgrading the libcurl used by php recently. we expect that the new version of libcurl supports millisecond-level timeout, so that we can control the backend interface timeout more precisely, this improves the overall response time.

However, we found that on our CentOS server, when you set a Timeout value less than Ms, curl will not initiate any request, but will directly return a Timeout error (Timeout reached 28 ).

Originally, there was a pitfall here. CURL is the default. in Linux, if the system standard DNS resolution is used, SIGALARM will be used to control domain name resolution timeout, however, SIGALARM does not support timeout of less than 1 S. Therefore, in the code of libcurl 7.28.1 (note the Chinese comment line ):

Int Curl_resolv_timeout (struct connectdata * conn,
  • Const char * hostname,
  • Int port,
  • Struct Curl_dns_entry ** entry,
  • Long timeoutms)
  • {
  • .......
  • .......
  • # Ifdef USE_ALARM_TIMEOUT
  • If (data-> set. no_signal)
  • /* Ignore the timeout when signals are disabled */
  • Timeout = 0;
  • Else
  • Timeout = timeoutms;
  • If (! Timeout)
  • /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
  • Return Curl_resolv (conn, hostname, port, entry );
  • If (timeout <1000) // if it is less than 1000, the system returns a timeout value.
  • /* The alarm () function only provides integer second resolution, so if
  • We want to wait less than one second we must bail out already now .*/
  • Return CURLRESOLV_TIMEDOUT;
  • ....
  • ....

It can be seen that when your Timeout time is less than Ms, name resolution will directly return CURLRESOLV_TIMEOUT, which will eventually lead to CURLE_OPERATION_TIMEDOUT, and then Error, Timeout reached...

This .... Is it too bad? Is it hard to say that we cannot Time Out in milliseconds? What do you do with this function?

Check the code or the code just now. pay attention to this (Chinese comment line ):

 
  • # Ifdef USE_ALARM_TIMEOUT
  • If (data-> set. no_signal) // pay attention to this line
  • /* Ignore the timeout when signals are disabled */
  • Timeout = 0;
  • Else
  • Timeout = timeoutms;
  • If (! Timeout)
  • /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
  • Return Curl_resolv (conn, hostname, port, entry );
  • If (timeout <1000)
  • /* The alarm () function only provides integer second resolution, so if
  • We want to wait less than one second we must bail out already now .*/
  • Return CURLRESOLV_TIMEDOUT;

It seems that as long as set. no_signal is 1, it can be bypassed... What is this?

This is simple, grep the code, and found:

 
  • Case CURLOPT_NOSIGNAL:
  • /*
  • * The application asks not to set any signal () or alarm () handlers,
  • * Even when using a timeout.
  • */
  • Data-> set. no_signal = (0! = Va_arg (param, long ))? TRUE: FALSE;
  • Break;

Haha:

 
  • Curl_setopt ($ ch, CURLOPT_NOSIGNAL, 1 );
  • ?>

After this OPT is added, everything is finally normal!

Postscript:

In this way, there will be a hidden risk, that is, DNS resolution will not be limited by timeout, which is because within the company, there is generally no problem, but in case of the DNS server hang, the application may time out.

Is there any other way?

Yes, that's what Mike reminds us. we can make libcurl use c-ares (C library for asynchronous DNS requests) for name resolution. The details can be found at config curl:

 
  • ./Configure -- enable-ares [= PATH]

In this way, you do not need to set NOSIGNAL.

PS. why do I just wonder why they don't need setimer?

Reference: http://stackoverflow.com/questions/7987584/curl-timeout-less-than-1000ms-always-fails
Author: Laruence
Address: http://www.laruence.com/2014/01/21/2939.html

Wait, expect the new version of libcurl to support millisecond-level timeout, so as to more precisely control the backend interface timeout, thus improving the overall response...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.