PHP如何优化网络请求_高并发HTTP请求优化说明【教程】

6次阅读

应使用 curl 多路复用替代循环 file_get_contents,因其通过共享连接、dns 缓存和 ssl 会话实现真正异步并发,避免阻塞与重复建连开销,并需正确配置 curlopt_dns_cache_timeout、tcp_keepalive、ssl 验证及 http/2 等参数以优化性能。

PHP如何优化网络请求_高并发HTTP请求优化说明【教程】

cURL 多路复用替代循环 file_get_contents

直接用 file_get_contents 发多个 HTTP 请求,在高并发下会卡死或超时,本质是阻塞式串行执行。php 本身不支持原生并发 HTTP,必须靠 cURLcurl_multi_* 系列函数做异步复用。

关键不是“能不能发”,而是“连接要不要重复建”。每次 curl_exec 都新建 TCP 连接,开销极大;而 curl_multi_exec 复用同一个 cURL 句柄池,底层共享连接、DNS 缓存和 SSL 会话。

  • 必须显式调用 curl_multi_setopt($mh, CURLMOPT_PIPELINING, 1) 启用管线化(PHP 7.2.22+ / 8.0+)
  • 每个子请求的 CURLOPT_RETURNTRANSFER 必须设为 true,否则结果拿不到
  • 别忘了 curl_multi_remove_handle 清理已完成句柄,否则内存泄漏
  • 错误检查不能只看 curl_multi_info_read 返回值,还要查 curl_error($ch)curl_getinfo($ch, CURLINFO_HTTP_CODE)
while ($active && $mrc == CURLM_OK) {     if (curl_multi_select($mh, 1) > 0) {         do {             $mrc = curl_multi_exec($mh, $active);         } while ($mrc == CURLM_CALL_MULTI_PERFORM);     } }

curl_setopt 关键参数避坑清单

很多性能问题其实出在几个默认参数上:DNS 缓存关闭、SSL 验证强制开启、连接不复用。不改这些,curl_multi 也白搭。

  • CURLOPT_DNS_CACHE_TIMEOUT 设为 600(秒),避免反复查 DNS
  • CURLOPT_TCP_KEEPALIVE 设为 1,保持空闲连接存活
  • CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST 在内网或可信环境可关(设为 false),省掉证书链校验耗时
  • CURLOPT_CONNECTTIMEOUT_MSCURLOPT_TIMEOUT_MS 更重要——它控制建连阶段,建议设 1500~3000ms,防止卡在 SYN 重传
  • 务必加 CURLOPT_USERAGENT,某些 CDN 或 API 网关会拦截空 UA 请求

并发数不是越大越好:受限于 PHP 的 max_connections 和系统文件描述符

你设了 100 个并发,但 PHP-FPM 的 pm.max_children 是 32,或者系统 ulimit -n 是 1024,那实际能跑的远少于预期,还会触发 Too many open files 错误。

立即学习PHP免费学习笔记(深入)”;

  • 先用 cat /proc/$(pgrep php-fpm)/limits | grep "Max open files" 查当前限制
  • 单次 curl_multi 并发建议控制在 20~50,再高收益递减,错误率上升
  • 如果要处理上千 URL,得自己分批 + 异步队列,别指望一次全塞进 curl_multi
  • 注意 curl_multi_add_handle 后不能立刻 unset($ch),句柄还被多路复用器持有,得等 curl_multi_remove_handle 之后再释放

别忽略 DNS 和 TLS 握手的隐性延迟

一个 https 请求里,DNS 查询和 TLS 握手占总耗时 30%~60%,尤其首次访问新域名时。PHP 不像 Node.js 或 Go 那样有全局 DNS 缓存池,每次都要走系统 resolver。

  • curl_setopt($ch, CURLOPT_RESOLVE, ["example.com:443:192.0.2.1"]) 强制指定 IP,跳过 DNS
  • 对固定后端服务,提前用 gethostbyname 解析一次,缓存 IP 列表,构造 CURLOPT_RESOLVE 数组
  • TLS 层面,启用 CURLOPT_SSL_ENABLE_NPNCURLOPT_SSL_ENABLE_ALPN(PHP 7.3.5+),支持 HTTP/2 协议协商加速
  • 如果目标服务支持 HTTP/2,且你用的是 libcurl 7.62.0+,记得加 CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0

真正卡住你的,往往不是代码逻辑,而是没意识到 DNS 和 TLS 是串行阻塞点,更不会自动复用。把这两个环节稳住,QPS 提升比调并发数明显得多。

text=ZqhQzanResources