curl的--connect-timeout与--max-time参数未按预期工作问题排查
问题:curl在Ubuntu 22.04中超时参数不生效的异常
问题场景
在Ubuntu 22.04系统执行以下curl命令时,实际等待时间远超设定的60秒:
curl --verbose --retry-max-time 0 --retry 0 --connect-timeout "30" --max-time "60" "https://www.google.com/"
测试结果
root@test:~# echo $(date) Tue Dec 6 07:26:04 PM CST 2022 root@test:~# curl --verbose --retry-max-time 0 --retry 0 --connect-timeout "30" --max-time "60" "https://www.google.com/" * Resolving timed out after 30000 milliseconds * Closing connection 0 curl: (28) Resolving timed out after 30000 milliseconds root@test:~# echo $(date) Tue Dec 6 07:28:26 PM CST 2022
注:实际耗时约142秒,远超设定的30秒连接超时和60秒总超时阈值
使用的curl版本
root@test:~# curl --version curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.12 Release-Date: 2022-01-05 Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd
预期行为
由于已出现DNS解析超时,整体耗时不应超过30秒或60秒。
原因分析
当前使用的curl版本启用了AsynchDNS特性(从版本信息的Features字段可见),异步DNS解析的超时逻辑与--connect-timeout、--max-time参数存在交互问题:
--connect-timeout仅控制TCP连接阶段的超时,异步DNS解析的超时不受该参数直接约束- 系统DNS解析配置(如
/etc/resolv.conf中的options timeout:n attempts:m)会决定实际解析耗时:如果配置了多次重试,每次超时n秒,总解析耗时会达到n*m秒,这部分时间无法被--max-time正确统计,导致总耗时远超设定值
修复方法
有两种可行的修复方案:
方案1:禁用异步DNS解析
在curl命令中添加--disable-async-dns参数,强制使用同步DNS解析,让--connect-timeout和--max-time能正确控制整体超时:
curl --verbose --disable-async-dns --retry-max-time 0 --retry 0 --connect-timeout "30" --max-time "60" "https://www.google.com/"
方案2:调整系统DNS解析配置
修改/etc/resolv.conf,减少DNS解析的重试次数和单次超时时间,示例配置:
options timeout:5 attempts:2
注:单次超时5秒,重试2次,总解析耗时最多10秒,加上30秒连接超时,总耗时不会超过40秒,符合预期
修改后保存文件,后续curl请求的DNS解析耗时会被控制在合理范围内
内容的提问来源于stack exchange,提问作者stackbiz
相关产品推荐
相关产品推荐

