Symfony HttpClient需显式设置timeout(10~15秒)和max_duration(20秒),禁用retry_failed,检查Content-Type再解析JSON,并限制max_connections防连接泄漏。

别用 cURL 手写,直接上 Symfony HttpClient,超时控制更稳、更少坑。
HttpClient::create() 怎么设请求超时
调用百度 API 时卡死,90% 是因为没设 timeout 或设错位置。Symfony HttpClient 默认连接超时 5 秒、总请求超时 30 秒,但百度接口响应波动大(尤其鉴权或大模型类),建议显式缩短并区分阶段:
-
timeout:整个请求生命周期上限(含 DNS、连接、发送、接收),单位秒,推荐设为10~15 -
max_duration:强制中断总耗时(比timeout更硬),适合防彻底卡死,设为20即可 - 不要混用
connect_timeout和timeout—— HttpClient 不认前者,只认timeout和max_duration
示例:
$client = HttpClient::create();
$response = $client->request('POST', 'https://aip.baidubce.com/rpc/2.0/xxx', [
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([...]),
'timeout' => 12,
'max_duration' => 20,
]);
百度返回非 JSON 时 toArray() 会炸,怎么防
百度某些错误场景(如 token 过期、配额超限)返回的是 HTML 或纯文本,$response->toArray() 直接抛 JsonException,不是 HTTP 状态码问题,而是解析失败。不提前检查就 catch 异常,日志里只会看到“JSON decode error”,根本看不出是百度返回了错误页。
- 先用
$response->getHeaders()['content-type'][0]判断是否含application/json - 如果不是,用
$response->getContent()拿原始内容,再人工分析(比如是否含"error_code") - 别在控制器里写这种判断——封装进 service 方法,统一处理百度特有的错误格式
典型百度错误响应头:text/plain; charset=utf-8 或 text/html,内容可能是 {"error_msg":"access_token invalid"},但 contentType 不是 JSON,toArray() 就挂。
调用百度文档解析API,支持18+格式,提取文本、表格、版面分析、OCR识别及RAG文档分块。适用于文档解析、文本/表格提取、结构分析、扫描件处理。触发词:文档解析、PDF解析、Word解析、表格提取、OCR、文档分析、提取文本、文档结构、扫描识别。
如何避免百度接口反复重试导致配额耗尽
Symfony HttpClient 默认重试 1 次(5xx 时),但百度部分接口(如 OCR、语音合成)对重试敏感:一次失败后重试,可能被算作两次调用,迅速吃光免费额度。
- 关掉自动重试:
'retry_failed' => false - 若需重试,必须自己控制逻辑:比如仅对
429(配额满)或网络错误重试,且加退避(usleep(500000)) - 百度返回的
X-RateLimit-Remaining头要记录,接近 0 时主动降级或告警,别等它崩
错误示范:$client->withOptions(['retry_failed' => true]) —— 百度不支持标准 RFC 重试语义,盲目开重试等于自废额度。
超时后连接没释放?得手动清理
HttpClient 在超时后会关闭底层 socket,但如果你在 service 中复用同一个 $client 实例,且没设 max_connections,高并发下可能堆积大量半开连接,最终触发“Too many open files”。
- 给 client 加连接池限制:
HttpClient::create(['max_connections' => 20]) - 别在循环里 new HttpClient —— 它是轻量单例,应注入容器复用
- 百度域名(
aip.baidubce.com)建议单独配置base_uri,避免每次拼 URL 出错
真正卡死往往不是百度慢,而是你没管住自己的连接数和重试逻辑。超时只是表象,背后是连接泄漏 + 无脑重试 + 错误类型误判三连击。

















