商务合作加微信:2230304070 

学习与交流:PHP技术交流微信群 

JetBrains 激活码 每月更新 免费提取

https://web.52shizhan.cn

接口调用慢、第三方 API 无响应、爬虫卡死、脚本执行中断……

这些问题大多数最终都会指向一个核心问题:超时(Timeout)

很多开发者只会简单调大 CURLOPT_TIMEOUT,但实际上超时问题通常发生在多个层级:

  • 网络连接层

  • HTTP 传输层

  • PHP 执行层

  • Web Server 层

  • 架构层(同步 → 异步)

本文从实际开发角度,系统讲清 PHP 请求超时的解决方案。


一、先理解:HTTP 请求为什么会超时?

一次 HTTP 请求通常经历:

客户端
 ↓
DNS解析
 ↓
TCP连接
 ↓
SSL握手(HTTPS)
 ↓
发送请求
 ↓
服务器处理
 ↓
返回响应

对应两类核心超时。

1. 连接超时(Connect Timeout)

表示:

客户端等待建立连接的最大时间。

包含:

  • DNS 查询

  • TCP 三次握手

  • SSL 握手

典型报错:

curl: (28) connect() timed out

常见原因:

  • 服务不可达

  • 网络抖动

  • DNS 异常

  • 防火墙限制


2. 传输超时(Request / Read Timeout)

表示:

连接建立成功后,等待完整响应的最大时间。

典型报错:

curl: (28) Operation timed out

常见原因:

  • 服务端处理慢

  • 返回数据过大

  • 网络传输阻塞


二、PHP cURL 超时配置(推荐生产方案)

不要只配置一个超时时间。

推荐:

<?php

$url = 'https://api.example.com/data';

$ch = curl_init($url);

curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,

    // 建立连接最长等待
    CURLOPT_CONNECTTIMEOUT => 5,

    // 整体请求最大耗时
    CURLOPT_TIMEOUT => 15,

    // HTTPS环境建议开启验证
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
]);

$response = curl_exec($ch);

if ($response === false) {

    $errno = curl_errno($ch);

    switch ($errno) {

        case CURLE_OPERATION_TIMEDOUT:
            thrownew RuntimeException(
                '请求超时,请检查服务响应时间'
            );

        case CURLE_COULDNT_CONNECT:
            thrownew RuntimeException(
                '连接失败,请检查网络'
            );

        default:
            thrownew RuntimeException(
                curl_error($ch)
            );
    }
}

$status = curl_getinfo(
    $ch,
    CURLINFO_HTTP_CODE
);

curl_close($ch);

if ($status !== 200) {
    thrownew RuntimeException(
        "HTTP状态异常:{$status}"
    );
}

$data = json_decode(
    $response,
    true
);

print_r($data);


超时参数建议

参数

作用

推荐值

CURLOPT_CONNECTTIMEOUT

建立连接超时

3–5 秒

CURLOPT_TIMEOUT

请求总超时

10–30 秒

CURLOPT_LOW_SPEED_TIME

低速持续时间

10 秒

CURLOPT_LOW_SPEED_LIMIT

最低传输速率

100B/s

增加低速保护:

curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, 10);
curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 100);

作用:

如果连续 10 秒速度低于 100B/s,则主动中断请求。


三、PHP 脚本执行超时(避免程序被强制终止)

即使 cURL 不超时,PHP 自己也可能先结束。

查看配置:

php -i | grep max_execution_time

默认:

max_execution_time = 30

临时调整执行时间

// 当前脚本最多执行120秒
set_time_limit(120);

特殊任务:

set_time_limit(0);

注意:

无限执行只适用于:

  • 队列消费

  • 数据迁移

  • 后台任务

不建议用于:

  • Web 请求

  • 接口服务

推荐生产配置:

max_execution_time=60
memory_limit=256M

四、长连接场景实践(SSE 实时推送)

适用于:

  • 实时监控

  • 日志流

  • 消息通知

  • AI 输出流

示例:

<?php

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');

ob_implicit_flush(true);

set_time_limit(0);

while (true) {

    echo"data: " . json_encode([
        'time' => date('H:i:s'),
        'memory' => memory_get_usage(true),
    ]) . "

";

    @ob_flush();
    flush();

    if (connection_aborted()) {
        break;
    }

    sleep(5);
}

浏览器连接:

const source =
    new EventSource('/server.php');

source.onmessage = e => {
    console.log(
        JSON.parse(e.data)
    );
};


五、服务端配置也会导致超时

很多人只改 PHP。

实际上还有这些限制:

Nginx

proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

PHP-FPM

request_terminate_timeout=60

MySQL

wait_timeout=300
connect_timeout=10

六、超时问题排查流程(建议收藏)

先确认问题在哪一层:

超时
 ↓
能否 ping 通?
 ↓
能否 telnet 端口?
 ↓
curl 是否超时?
 ↓
服务日志是否异常?
 ↓
PHP执行时间是否结束?
 ↓
数据库是否阻塞?

常用命令:

网络:

ping api.example.com

telnet api.example.com 443

查看接口耗时:

curl 
-w "
DNS:%{time_namelookup}
TCP:%{time_connect}
TTFB:%{time_starttransfer}
TOTAL:%{time_total}

https://api.example.com

查看 PHP:

ps aux | grep php

查看资源:

top

七、终极方案:不要和超时硬碰硬

如果业务允许,优先避免同步等待。

推荐架构:

用户请求
 ↓
立即返回
 ↓
消息队列
 ↓
异步执行
 ↓
结果通知

常见方案:

  • RabbitMQ

  • Redis Queue

  • Kafka

  • Swoole 协程

  • Laravel Queue

这样可以从根本上降低接口超时风险。


总结

遇到 PHP HTTP 超时,不要只改:

CURLOPT_TIMEOUT

建议按顺序检查:

① 网络连接
② cURL 超时配置
③ PHP 执行时间
④ Nginx / PHP-FPM 限制
⑤ 数据库耗时
⑥ 是否改造成异步架构

真正稳定的方案,不是把超时时间无限调大,而是控制链路耗时 + 降低同步等待


参考链接:

以上就是本篇分钟的全部内容,希望各位程序员们努力提升个人技术。最后,小编温馨提示:每天阅读5分钟,每天学习一点点,每天进步一点点。