Hyperf 3.2 中 read_timeout 非全局配置,需按组件分别设置:Guzzle 用 options.timeout(等效 read_timeout),Redis 在 redis.php 中配 read_timeout,MySQL 在 DSN 中加 read_timeout=3,还需协程级 timeout 兜底防卡死。

Hyperf 3.2 中的 read_timeout 不是框架层统一配置项,而是分组件生效的底层连接参数。它主要作用于 HTTP 客户端(如 Guzzle)、Redis、数据库连接等 I/O 操作,目的是防止因远端响应慢或网络异常导致协程长时间阻塞。卡死往往不是因为没设 timeout,而是设错位置或值不合理。
HTTP 客户端的 read_timeout 配置
Hyperf 默认使用 hyperf/guzzle,超时由 Guzzle 的 timeout 和 connect_timeout 控制,其中 timeout 等效于 read_timeout(即从连接建立后开始计时的总等待时间)。
- 在
config/autoload/clients.php中配置:
'guzzle' => [
'handler' => \Hyperf\Guzzle\HandlerStackFactory::class,
'options' => [
'timeout' => 5.0, // ⚠️ 关键:等效 read_timeout,单位秒,建议 3–10
'connect_timeout' => 3.0, // 连接建立阶段超时
'http_errors' => false, // 避免 4xx/5xx 直接抛异常中断流程
],
],
- 调用时也可动态覆盖:
$client->get($url, ['timeout' => 2.5]) - 注意:设为
0或false表示无限等待,生产环境严禁
Redis 的 read_timeout 设置
Hyperf 使用 Swoole\Coroutine\Redis,其 read_timeout 是连接级参数,需在 Redis 配置中显式指定:
- 修改
config/autoload/redis.php:
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'auth' => env('REDIS_AUTH', null),
'port' => (int) env('REDIS_PORT', 6379),
'db' => (int) env('REDIS_DB', 0),
'read_timeout' => 3.0, // ✅ 显式设置,单位秒,推荐 2–5
'write_timeout' => 3.0,
'timeout' => 3.0, // 向后兼容旧版写法(部分版本仍识别)
],
- 该参数直接影响
get、hGetAll等命令——大 key 或高延迟 Redis 实例下不设会卡住整个协程 - 若使用 Redis Cluster,每个节点连接都需单独配置
read_timeout
数据库连接的 read_timeout(MySQL / PostgreSQL)
Hyperf 的 hyperf/db 基于 PDO,不直接暴露 read_timeout,但可通过 PDO DSN 参数注入:
- 在
config/autoload/databases.php的 DSN 中添加read_timeout=3:
'mysql' => [
'driver' => env('DB_DRIVER', 'mysql'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'hyperf'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => env('DB_PREFIX', ''),
'strict' => true,
'options' => [
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
],
'dsn' => env('DB_DSN', 'mysql:host=localhost;port=3306;dbname=hyperf;charset=utf8mb4;read_timeout=3'), // ✅ 加在这里
],
- MySQL 服务端也需开启
wait_timeout和interactive_timeout配合(建议设为 300 秒以上) - PostgreSQL 可用
options='--client-min-messages=warning -c statement_timeout=3000'控制语句级超时
全局协程超时兜底(防漏网之鱼)
即使各组件设了 timeout,业务逻辑中手动 sleep、密集计算或未封装的第三方 SDK 仍可能卡住。推荐加一层协程级保护:
- 在关键异步任务外包裹
timeout:
use Hyperf\Coroutine\Coroutine;
$result = Coroutine::timeout(8.0, function () {
return $this->heavyService->process();
});
if ($result === false) {
throw new \RuntimeException('Operation timed out');
}
- 对 Controller 方法,可用注解 + 自定义中间件实现统一超时拦截(例如
@Timeout(10)) - 注意:Swoole 的
max_coroutine和coroutine.stack_size也要合理配置,避免协程栈溢出引发假死











