Curl的毫秒超时的一个”Bug”
Curl的毫秒超时的一个”Bug”
-- PHP老杨
最近我们的服务在升级php使用的libcurl, 期望新版本的libcurl支持毫秒级的超时, 从而可以更加精细的控制后端的接口超时, 从而提高整体响应时间.
但是, 我们却发现, 在我们的CentOS服务器上, 当你设置了小于1000ms的超时以后, curl不会发起任何请求, 而直接返回超时错误(Timeout reached ).
原来, 这里面有一个坑, CURL默认的, 在Linux系统上, 如果使用了系统标准的DNS解析, 则会使用SIGALARM来提供控制域名解析超时的功能, 但是SIGALARM不支持小于1s的超时, 于是在libcurl 7.28.1的代码中(注意中文注释行):
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 = ;
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;
....
....
可见, 当你的超时时间小于1000ms的时候, name解析会直接返回CURLRESOLV_TIMEOUT, 最后会导致CURLE_OPERATION_TIMEDOUT, 然后就Error, Timeout reached了…
这….太坑爹了吧? 难道说, 我们就不能使用毫秒超时么? 那你提供这功能干啥?
还是看代码, 还是刚才那段代码, 注意这个(中文注释行):
#ifdef USE_ALARM_TIMEOUT
if(data->set.no_signal) //注意这行
/* Ignore the timeout when signals are disabled */
timeout = ;
else
timeout = timeoutms;
if(!timeout)
/* USE_ALARM_TIMEOUT defined, but no timeout actually requested */
return Curl_resolv(conn, hostname, port, entry);
if(timeout < )
/* 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;
看起来, 只要set.no_signal 这个东西为1, 就可以绕过了… 那这个玩意是啥呢?
这就简单了, grep一下代码, 发现:
case CURLOPT_NOSIGNAL:
/*
* The application asks not to set any signal() or alarm() handlers,
* even when using a timeout.
*/
data->set.no_signal = ( != va_arg(param, long))?TRUE:FALSE;
break;
哈哈, 原来是这货:
<?php
curl_setopt($ch, CURLOPT_NOSIGNAL, );
?>
加上这个OPT以后, 一切终于正常了!
后记:
这样一来, 就会有一个隐患, 那就是DNS解析将不受超时限制了, 这在于公司内部来说, 一般没什么问题, 但是万一DNS服务器hang住了, 那就可能会造成应用超时.
那么还有其他办法么?
有, 那就是Mike提醒的, 我们可以让libcurl使用c-ares(C library for asynchronous DNS requests)来做名字解析. 具体的可以在config curl的时候:
./configure --enable-ares[=PATH]
这样就可以不用设置NOSIGNAL了
Curl的毫秒超时的一个”Bug”的更多相关文章
- curl毫秒超时使用的坑
升级后的libcurl已经支持了毫米级别的超时.但是使用的时候还有一个坑需要注意跨过去 . libcurl如果检查到设置的timeout < 1s 那么会直接发出一个信号说 "已经超时 ...
- 我是一个Bug, 终极大Bug
我是一个Bug ,在这个系统中潜伏很久了,历经多轮测试的严酷考验而屹立不倒,如果Bug界按难度分类的话,我绝对属于地狱模式. 现在,我就等待一个倒霉蛋来触发, 可是他老是不来. 其实不能叫倒霉蛋 , ...
- Tomcat一个BUG造成CLOSE_WAIT
之前应该提过,我们线上架构整体重新架设了,应用层面使用的是Spring Boot,前段日子因为一些第三方的原因,略有些匆忙的提前开始线上的内测了.然后运维发现了个问题,服务器的HTTPS端口有大量的C ...
- MySQL关于exists的一个bug
今天碰到一个很奇怪的问题,关于exists的, 第一个语句如下: SELECT ) FROM APPLY t WHERE EXISTS ( SELECT r.APPLY_ID FROM RECORD ...
- 由一个bug引发的SQLite缓存一致性探索
问题 我们在生产环境中使用SQLite时中发现建表报“table xxx already exists”错误,但DB文件中并没有该表.后面才发现这个是SQLite在实现过程中的一个bug,而这个bug ...
- Win10系统菜单打不开问题的解决,难道是Win10的一个Bug ?
Win10左下角菜单打不开,好痛苦,点击右下角的时间也没反应,各种不爽,折磨了我好几天,重装又不忍心,实在费劲,一堆开发环境要安装,上网找了很多方法都不适用.今天偶然解决了,仔细想了下,难道是Win1 ...
- 你可能不知道的 NaN 以及 underscore 1.8.3 _.isNaN 的一个 BUG
这篇文章并不在我的 underscore 源码解读计划中,直到 @pod4g 同学回复了我的 issue(详见 https://github.com/hanzichi/underscore-analy ...
- 标准模板库(STL)的一个 bug
今天敲代码的时候遇到 STL 的一个 bug,与 C++ 的类中的 const 成员变量有关.什么,明明提供了默认的构造函数和复制构造函数,竟然还要类提供赋值运算符重载.怎么会这样? 测试代码 Tes ...
- 是uibutton跟tableviewcell同步使用一个bug
这个问题是uibutton跟tableviewcell同步使用一个bug,不关delay一点毛事,证据就是点击事件没问题,so,搜到一个方法解决了这个问题.uibutton分类symbian2+ios ...
随机推荐
- Optimistic Offline Lock乐观离线锁
通过冲突检测和(发生冲突时的)事务回滚,来防止并发业务事务中的冲突. 通常一个业务事务的执行,会跨越一系列的系统事务. 一旦超出了单个系统事务的范围,就不能仅依靠DB管理程序来保证数据一致性. 乐观离 ...
- (转)从集中到分布,解读网络视频IT架构变迁
2006年以视频网站为代表的网络视频行业迅速崛起,IPTV.视频分享网站.视频搜索网站.提供视频服务的互动社区.交友.播客等等新兴媒体发展迅猛.网络视频行业现已成为众多资本机构关注与投资的焦点.但是在 ...
- call与apply函数
call与apply函数 1.为什么需要call与apply函数 Javascript中,每一个函数内部都有一个特殊的关键词this,其随着所处环境的不同其指向也是不同的. 函数的内部其this也是指 ...
- db.properties 数据库配置文件
project.pool.initialPoolSize project.pool.minPoolSize project.pool.maxPoolSize project.db.tablePrefi ...
- virtualbox安装增强包及配置共享文件夹
因为需要在host及虚拟机间传输数据,想使用共享文件夹.但是单独设置了共享文件夹后在centos里找不到共享文件夹,看了下要安装增强包.好吧,顺 便也解决下鼠标切换的问题,省的老是按右CTL切换 ...
- 引入OO开发报表后的感想
很早就想尝试着在常规的报表开发中 引入OO了 趁着程序略复杂 时间略充裕 终于尝试了一把-咩哈哈~~ 以下来自我的evernote笔记 有点语无伦次-忍忍~~ -------------------- ...
- Python单元测试——深入理解unittest (转)
单元测试的重要性就不多说了,可恶的是Python中 有太多的单元测试框架和工具,什么unittest, testtools, subunit, coverage, testrepository, no ...
- nss_12 上传文件后返回jsonresult结果,IE中出现文件下载框
因为控制器返回的是JsonResult, 但是在IE8中一直返回文件下载的对话框. 转到谷歌浏览器倒没有问题. 网上找的方法, 要么是跟到一个新的成功页面, 要么是直接返回html, 觉得应该有更好的 ...
- php读取excel文件的实例代码
php读取excel文件的实例代码. 代码: <?php /** * php读取excel文件 * by www.jbxue.com */ $this->loadexcel();//半酣p ...
- Python脚本控制的WebDriver 常用操作 <十三> 处理button group层的定位
下面将使用webdriver来定位同一层的按钮 测试用例场景 button group就是按钮组,将一组按钮排列在一起. 处理这种对象的思路一般是先找到button group的包裹(wrapper) ...