惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Security Latest
Security Latest
P
Palo Alto Networks Blog
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Latest news
Latest news
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
J
Java Code Geeks
P
Privacy International News Feed
阮一峰的网络日志
阮一峰的网络日志
S
Schneier on Security
博客园 - 聂微东
Project Zero
Project Zero
美团技术团队
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Scott Helme
Scott Helme
I
Intezer
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
S
Security @ Cisco Blogs
博客园 - 司徒正美
O
OpenAI News
Last Week in AI
Last Week in AI
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
SecWiki News
SecWiki News
月光博客
月光博客
S
Security Affairs
The GitHub Blog
The GitHub Blog
P
Privacy & Cybersecurity Law Blog
S
Secure Thoughts
V
V2EX
S
Securelist
F
Fortinet All Blogs
W
WeLiveSecurity
D
Docker
博客园 - 三生石上(FineUI控件)
Simon Willison's Weblog
Simon Willison's Weblog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cyber Attacks, Cyber Crime and Cyber Security
V
Visual Studio Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Engineering at Meta
Engineering at Meta

流动

对口型视频合成方案对比:Wav2Lip、VideoReTalking 与 MuseTalk 2026 音色克隆方案对比:IndexTTS-2、CosyVoice、GPT-SoVITS、Fish Speech、VoxCPM 部署与实测 AI Agent折腾记(OpenClaw / Hermes Agent) 我的2025年 大连之行 回家收麦 六一儿童节爬长城 Golang database/sql 数据库断线自动重连机制解析 Golang默认Http Client导致的cannot assign requested address错误 清明踏春,爬山看海 购入小牛G400T电动车 北京的三月飞雪 wrenAI本地LLM模型部署 天津一日游 2024年终总结 停止使用staticfile.org服务 使用 ImageMagick 自动添加水印,保护图片版权 如何注册一个.sol域名 奥森公园半日游 昌平42公里骑行绿道打卡 十月一日爬慕田峪长城 当Hugo遇上AVIF,优化图片加载 博客被恶意镜像 Github Pages 部署流程解析 搭建个人锻炼页面 你好 Follow 中秋爬山 Google Adsense的审核之旅 让你的IPFS站点持久在线:接入Filebase的Names(IPNS)服务 一次简短的青岛之行 解决 "undeclared name: any (requires version go1.18 or later)" 编译错误 搭建自托管IPFS Gateway服务,替代Cloudflare的IPFS Gateway 302跳转的跨域问题(CORS) GORM增加sqlcommenter特性 源码分析:GORM是如何生成sql的 工银亚洲网银密码重置 加速Cloudflare访问 2023年终总结 2023年12月北京暴雪记录 使用Hugo实现响应式和优化的图片 加速Google Analytics 使用Google Indexing API加速博客收录 在Netlify上部署Twikoo评论系统 利用Github Actions定时抓取微博 北大口腔牙周刮治记录 故乡回忆之旅 解决Golang使用go get安装包后找不到可执行文件的问题 修正Hugo的JSON Feed格式 我的学车之路 将博客部署到星际文件系统(IPFS) 新冠疫情后的第一个春节 第一次清理键盘 2022年终总结 去掉Cloudflare烦人的email-decode.min.js请求 累计布局偏移修复方案改进 —— 自动生成图片宽高 优化博客的累计布局偏移(CLS)问题 将博客部署到Cloudflare Pages 奥林匹克公园向日葵之旅 记第二次洗牙 记录2022年海淀幼升小 Golang解析json的一个问题 疫情下的生活 整理下博客的一些调整 疫情下的五一假期 自己动手,更换thinkpad x1硬盘 二刷百望山 带娃游颐和园 博客架构说明 难得的清明假期 十一年的等待,终于拿到了liudon.com域名 被隔离的一周 mysql中字符串和整型自动转换的问题 一次惊心动魄的Mysql更新操作 如何在北京公积金网站上修改婚姻状况 PHP7.2编译安装后没有php.ini文件的问题 检测网站支持的SSL/TLS协议版本 记一次难忘的手术经历 十一假期经历 Swoft 框架运行分析(五) —— ConsoleProcessor模块分析 Swoft 框架运行分析(四) —— EventProcessor模块分析 一个git submodule update引发的问题 Swoft 框架运行分析(三) —— BeanProcessor模块分析 Swoft 框架运行分析(二) —— AnnotationProcessor模块分析 Swoft 框架运行分析(一) BCMath 与 科学计数 Flink Could Not Resolve Resourcemanager Address 解决Sublime Text安装包时"There Are No Packages Available for Installation"的报错 关于本站 2019,新开始
一个Curl的耗时长的问题
Liudon · 2019-09-04 · via 流动

发现某个接口请求很慢,但是后端确认接口是很快的。

在机器上通过shell执行curl命令,确实很快,但是PHP代码里请求又确实很慢。

业务里用到了Requests这个库,一开始以为是这个库导致的问题。

Requests_Transport_cURL类里断点定位了下,确实很慢,curl_getinfo返回的信息如下。

array (
  'url' => 'http://xxxxx',
  'content_type' => 'text/html',
  'http_code' => 200,
  'header_size' => 64,
  'request_size' => 305,
  'filetime' => -1,
  'ssl_verify_result' => 0,
  'redirect_count' => 0,
  'total_time' => 2.074094,
  'namelookup_time' => 2.5E-5,
  'connect_time' => 0.032107,
  'pretransfer_time' => 0.032109,
  'size_upload' => 186,
  'size_download' => 99,
  'speed_download' => 47,
  'speed_upload' => 89,
  'download_content_length' => 99,
  'upload_content_length' => 186,
  'starttransfer_time' => 2.032866,
  'redirect_time' => 0,
  'certinfo' =>
  array (
  ),
)

这里可以看到starttransfer_time时间很长。

搜索了一番,发现网上一个case,cURL slow starttransfer_time

里面提供了Expect: 100-continue这个header,又搜索了一番这个header资料。

curl在发POST请求的时候,如果body大于1k:

  1. 先追加一个Expect: 100-continue请求头信息,发送这个不包含 POST 数据的请求;
  2. 如果服务器返回的响应头信息中包含Expect: 100-continue,则表示 Server 愿意接受数据,这时才 POST 真正数据给 Server; 如果等待1s,没有收到服务器肯定或否定的应答,那么继续发起POST请求,这种会导致请求耗时变长。

在机器上抓了个包,执行下面命令。

注意,下面port后面的80改成实际的端口

tcpdump -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

拿到的包信息。

09:17:19.421587 IP xxx.54360 > xxxxx:12345: Flags [P.], seq 767181008:767181314, ack 353986709, win 115, options [nop,nop,TS val 2628114858 ecr 1424896084], length 306
E..f.m@.@...d}@.        A...XF.-.@...h....s.......
....T.0TPOST /cgi HTTP/1.1
User-Agent: php-requests/1.6
Accept: */*
Accept-Encoding: deflate, gzip
Referer: http://xxxxx:12345/cgi
Content-Length: 188
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------ee2f4d848646


09:17:21.421786 IP xxx.54360 > xxxxx:12345: Flags [P.], seq 306:494, ack 1, win 115, options [nop,nop,TS val 2628115359 ecr 1424896091], length 188
E....n@.@..Md}@.        A...XF.-.B...h....s./.....
....T.0[------------------------------ee2f4d848646
Content-Disposition: form-data; name="req"

{"command":"zzz","appId":"yyyy"}
------------------------------ee2f4d848646--

09:17:21.458628 IP xxxxx:12345 > xxx.54360: Flags [P.], seq 1:118, ack 494, win 130, options [nop,nop,TS val 1424896593 ecr 2628115359], length 117
E...X.@.5.Q2    A..d}@.F..X..h.-.B......3.....
T.2Q....HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 53

{
    "data": [],
    "errno": 0,
    "error": "ok"
}

可以看到确实是先发了一个100-continue的请求,然后再发的实际POST请求。

在机器上执行下面的shell命令。

curl 'http://xxxxx:12345/cgi' -H"Expect: 100-continue" -v

返回如下,可以看到返回的header头里确实没有Expect这项。

* About to connect() to xxxxx port 12345 (#0)
*   Trying xxxxx...
* Connected to xxxxx (xxxxx) port 12345 (#0)
> GET /cloud_cgi HTTP/1.1
> User-Agent: curl/7.29.0
> Host: xxxxx:12345
> Accept: */*
> Expect: 100-continue
> 
< HTTP/1.1 200 OK
< Content-Type: text/html
< Content-Length: 42
< 
* Connection #0 to host xxxxx left intact
{"errno":100,"error":"参数格式错误"}

解决方法:

请求的时候,header里新增一项。