Recently, our service is upgrading the libcurl used by PHP. We hope that the new version of libcurl will support millisecond timeouts, so that we can more precisely control the backend interface timeout, thereby improving the overall response time.
However, we found that on our CentOS server, when you set a timeout less than 1000ms, curl will not initiate any requests, but directly return a timeout error (Timeout reached 28).
It turns out that there is a pitfall here. CURL defaults to a Linux system. If the system standard DNS resolution is used, SIGALARM will be used to provide the function of controlling the domain name resolution timeout. However, SIGALARM does not support a timeout of less than 1s, so in In the code of libcurl 7.28.1 (note the Chinese comment line):
int Curl_resolv_timeout(struct connectdata *conn,It can be seen that when your timeout is less than 1000ms, name resolution will directly return CURLRESOLV_TIMEOUT, which will eventually lead to CURLE_OPERATION_TIMEDOUT, and then Error, Timeout reached...
Isn't this... too cheating? Can't we use millisecond timeout? Then why do you provide this function?
Let’s look at the code again, the same code just now, pay attention to this (Chinese comment line):
It seems that as long as set.no_signal is 1, it can be bypassed... So what is this thing?
This is easy, grep the code and find:
Haha, it turns out to be this guy:
After adding this OPT, everything is finally normal!
Postscript:
In this way, there will be a hidden danger, that is, DNS resolution will not be subject to timeout restrictions. This is generally not a problem within the company, but if the DNS server hangs, it may cause application timeout.
So is there any other way?
Yes, as Mike reminded us, we can let libcurl use c-ares (C library for asynchronous DNS requests) for name resolution. The specific details can be found when config curl:
This way you don’t need to set NOSIGNAL
PS, why is it called "Bug"? I'm just curious, why don't they use setitimer?
Reference: http://stackoverflow.com/questions/7987584/curl-timeout-less-than-1000ms-always-fails
Author: Laruence
URL of this article: http://www.laruence.com/2014/01/21/2939.html