php模拟post请求重试机制_phppost失败重试教程【技巧】

5次阅读

curl_exec()返回false时应先通过curl_errno()判断错误类型:CURLE_OPERATION_TIMEDOUT等底层网络错误可重试,curl_errno为0但无http响应或5xx状态码也可重试,4xx及业务错误不可重试;需配合curl_error()记录日志,合理设置超时时间(CONNECTTIMEOUT 3~5秒、TIMEOUT 10~15秒),采用带随机偏移的指数退避(如1/2/4秒)且最多重试3次;并发场景下失败请求须移出multi句柄后用独立cURL重试。

php模拟post请求重试机制_phppost失败重试教程【技巧】

curl_exec() 返回 false 时怎么判断是否该重试

phpcurl_exec() 发 POST 请求失败,不一定都要重试。得先区分是网络抖动(比如超时、连接拒绝),还是业务错误(比如接口返回 {"code":400,"msg":"参数错误"})。前者可重试,后者重试一百次也没用。

实操建议:

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

  • 检查 curl_errno($ch):值为 CURLE_OPERATION_TIMEDOUT(28)、CURLE_COULDNT_CONNECT(7)、CURLE_SEND_ERROR(55)等属于可重试的底层错误
  • curl_errno() 为 0,但 curl_exec() 返回 false,要结合 curl_getinfo($ch, CURLINFO_HTTP_CODE)状态码——0 表示根本没收到响应(大概率网络问题),5xx 可考虑重试,4xx 基本不重试
  • 别只依赖返回值真假,一定要配合 curl_error($ch) 打日志,否则重试五次失败,你连哪次卡在哪都不知道

设置合理的 CURLOPT_TIMEOUT 和 CURLOPT_CONNECTTIMEOUT

超时时间设太短,小概率丢包就直接失败;设太长,重试链路会卡住整个流程。尤其在高并发场景下,一个请求卡死 30 秒,可能拖垮整批任务。

实操建议:

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

  • CURLOPT_CONNECTTIMEOUT 控制建连阶段,建议设为 35 秒。dns 解析慢、目标机器 SYN 队列满都发生在这阶段,没必要等太久
  • CURLOPT_TIMEOUT 控制整个请求周期(含传输),建议设为 1015 秒。如果后端本身处理就要 8 秒,那这个值至少得留出缓冲
  • 千万别把两个 timeout 都设成 30 秒再搞 3 次重试——实际最长可能卡 90 秒,调用方早超时了

实现指数退避(exponential backoff)而不是固定间隔重试

连续请求失败时,立刻重试往往雪上加霜——对方服务可能正被压垮,你还在疯狂打它。固定等 1 秒重试,和等 1 秒、2 秒、4 秒,对下游压力完全不同。

实操建议:

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

  • 第 1 次失败后等待 1 秒,第 2 次失败后等待 2 秒,第 3 次失败后等待 4 秒(即 pow(2, $retryCount - 1)
  • 加个随机偏移(jitter),比如 sleep(rand(0, 1000) / 1000 + $backoff),避免所有客户端在同一时刻重试造成脉冲流量
  • 最大重试次数建议控制在 3 次以内。超过 3 次还失败,大概率是配置错、地址错、证书过期或对方服务不可用,人工介入比继续重试更有效

用 curl_multi_exec() 并发请求时重试要单独隔离

很多人用 curl_multi_exec() 批量发请求,发现某个子请求失败了,想单独重试它——但直接在 multi 句柄里塞新 handle 会破坏状态机,容易导致句柄泄漏或 curl_multi_exec() 返回 CURLM_CALL_MULTI_PERforM循环

实操建议:

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

  • 不要在 multi 流程中动态增删 handle。失败的请求,应从 multi 句柄中 curl_multi_remove_handle() 掉,再用独立的单 cURL 句柄重试
  • 重试后的结果,不要强行塞回原 multi 的回调逻辑里,而是单独处理响应、记录日志、更新状态
  • 如果必须批量重试,建议拆成两轮:第一轮用 multi 发,收集失败 ID;第二轮用单 cURL + 指数退避逐个重试,逻辑更可控

重试不是兜底银弹。真正难的不是写 for 循环,而是分清哪些错误能靠重试解决,哪些错误一出现就该报警、降级或跳过。尤其是跨公网调用第三方 API 时,对方的限流策略、证书更新、灰度发布,都会让“失败”变得五花八门。

text=ZqhQzanResources