ai接口不稳定时,第一道防线是curl网络层超时而非max_execution_time;须分设curlopt_connecttimeout_ms和curlopt_timeout_ms,禁用file_get_contents,配合显式错误检查与分级重试。

AI 接口响应不稳定时,max_execution_time 不是第一道防线——它管的是整个 PHP 脚本生命周期,而 AI 请求卡住,真正该控制的是网络层超时。直接调大 max_execution_time 只会让失败更隐蔽、更难定位。
cURL 请求必须分设连接与传输超时
只设 CURLOPT_TIMEOUT 是常见误区:它把“建连 + 等响应”捆在一起计时,但 AI 接口常出现“连得上却迟迟不返回 body”的情况(比如模型正在推理中)。此时连接已建立,CURLOPT_TIMEOUT 还没触发,脚本却卡在 curl_exec() 里不动。
正确做法是拆开控制:
-
CURLOPT_CONNECTTIMEOUT_MS设为 2000~3000(毫秒),防 DNS 解析慢或目标服务不可达 -
CURLOPT_TIMEOUT_MS设为 15000~30000(毫秒),覆盖完整请求周期,含等待模型推理完成时间 - 避免混用
_MS和非_MS参数(如同时设CURLOPT_TIMEOUT和CURLOPT_TIMEOUT_MS),后者会被前者覆盖 - 若服务明确支持流式响应(如 SSE),需额外设
CURLOPT_LOW_SPEED_LIMIT+CURLOPT_LOW_SPEED_TIME防止“假活”
file_get_contents 也能设超时,但不推荐用于 AI 请求
虽然可用 stream_context_create() 给 file_get_contents() 加 timeout,但它本质是阻塞式、无连接超时控制、无法区分“连不上”和“连上了不回”,且不支持 HTTP/2 或自定义 keep-alive 行为。
AI 接口通常要求:
- 携带
Authorization和Content-Type: application/json头 ——file_get_contents()需手动拼 header 字符串,易出错 - 接收大响应体(如长文本生成)—— 它默认把全部内容读进内存,OOM 风险高
- 需要检查真实 HTTP 状态码(而非仅判断是否返回字符串)—— 它不暴露状态码,得靠正则或额外
get_headers(),不可靠
结论:仅限调试或极简单 GET 请求,生产环境一律用 cURL。
重试机制必须配合超时,且不能无脑 retry
超时只是熔断,不是兜底。AI 接口失败后直接抛异常,用户看到白屏,不如按策略重试一次。
但重试前必须确认错误类型:
- 可重试:
CURLE_COULDNT_CONNECT、CURLE_OPERATION_TIMEDOUT、HTTP 状态码502/503/504 - 不可重试:
400(参数错)、401(token 失效)、429(限流)—— 重试只会放大问题 - 每次重试前用
usleep(100000)(100ms)起手,第二次翻倍,最多试 3 次(含首次) - 每次循环必须调用
curl_init()重建 handle,否则curl_setopt()可能复用旧状态,导致 header 或 timeout 错乱
别忽略 PHP 自身执行超时的兜底作用
cURL 层超时再细,也防不住 PHP 内部逻辑卡死(比如解析大 JSON 响应时死循环)。所以仍需设好脚本级超时:
- 脚本开头加
ini_set('max_execution_time', 60),比 cURL 总超时多留 10~20 秒缓冲 - 禁用
set_time_limit(0),除非你完全掌控所有下游行为(比如 CLI 后台任务) - 若用 PHP-FPM,注意
request_terminate_timeout(FPM 配置)可能比max_execution_time更早杀掉进程,需同步调整
最易被忽略的一点:cURL 超时错误不会自动触发 PHP 异常,必须显式检查 curl_errno($ch) 或 curl_getinfo($ch, CURLINFO_HTTP_CODE) 才能进入重试分支——漏掉这步,超时就等于静默失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











