cURL_multi_exec性能问题求助:如何实现每秒12次Twitch API请求?
问题描述
我需要向Twitch API发起每秒12次请求。目前通过3个进程实现,每个进程每秒串行执行4次查询,尝试改用curl_multi单进程处理但效果未达预期!
原本以为curl_multi能实现近乎同时的请求,但实际并非如此。当前使用file_get_contents串行请求,单次耗时约200-250ms,单进程每秒最多处理5次请求。
期望通过curl_multi实现每秒12次并发请求,虽速度有所提升,但12次查询实际耗时约1.3秒。用hrtime测量发现耗时集中在以下代码段:
do { curl_multi_exec($multihandle, $stillrunning); curl_multi_select($multihandle); } while($stillrunning > 0);
查阅资料得知cURL或存在性能问题,部分用户反馈其与OpenSSL 3库兼容不佳,有人回滚至OpenSSL 1.1版本,但这并非理想方案,且不确定能否解决我的问题。
系统环境:
- Linux Zoe2 5.15.0-94-generic #104-Ubuntu SMP Tue Jan 9 15:25:40 UTC 2024 x86_64
- PHP: 8.1.27版本
- cURL: 7.81.0
- SSL版本: OpenSSL/3.0.2
解决思路
1. 优化curl_multi事件循环逻辑
curl_multi_select()默认会阻塞等待活动连接,可设置短超时时间(比如1ms)避免无意义的长阻塞,同时添加执行状态判断:
do { $execReturnValue = curl_multi_exec($multihandle, $stillrunning); if ($stillrunning) { // 设置1ms超时,减少不必要等待 curl_multi_select($multihandle, 0.001); } } while ($stillrunning > 0 && $execReturnValue === CURLM_OK);
另外给所有curl句柄添加CURLOPT_NOSIGNAL => true配置,避免信号处理带来的性能损耗。
2. 调整SSL相关配置适配OpenSSL 3
针对OpenSSL 3的兼容问题,尝试给curl句柄添加以下配置:
// 测试阶段可临时关闭证书验证,生产环境需恢复 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 强制指定TLS协议版本,规避兼容问题 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
3. 替换为更高效的并发方案
如果curl_multi的性能瓶颈无法突破,可尝试替代方案:
- 使用Guzzle的异步请求模式,基于Promise实现并发,代码更简洁易维护
- 采用ReactPHP的事件循环异步HTTP客户端,高效处理大量并发请求
- 改用Swoole/Workerman等协程框架,常驻内存+协程的模式并发性能远超curl_multi
4. 优化多进程模型
回到多进程方案但优化进程内处理逻辑:
- 每个进程用curl_multi并发处理4次请求,而非串行执行,3个进程即可实现12次并发
- 共享Twitch API的令牌缓存,减少重复的SSL握手开销,避免进程间资源竞争
5. 排查Twitch API限流
检查响应头中的Ratelimit-Remaining和Ratelimit-Reset字段,确认是否触发了API的速率限制,导致请求被延迟处理。
内容的提问来源于stack exchange,提问作者Zoe Ballz
相关产品推荐
相关产品推荐

