如何使用ThinkPHP高效实现长连接请求处理?

2026-05-20 13:550阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1014个文字,预计阅读时间需要5分钟。

如何使用ThinkPHP高效实现长连接请求处理?

ThinkPHP 本身不支持真正意义上的长连接请求,所有长连接都需脱离 PHP-FPM 模式,改用 Swoole 或 Workerman 等常驻进程方案;在标准 Web 部署下,仅能依赖伪长轮询模拟。

为什么不能在控制器里用 sleep() 挂起请求

PHP-FPM 是同步阻塞模型,每个请求独占一个 worker 进程。写 sleep(5)while (!Redis::get($key)) { usleep(100000); } 会导致该 worker 被锁死,无法处理新请求。压测时很快出现超时、502、FPM 进程耗尽。

  • 即使加了 set_time_limit(0),也只延长脚本执行时间,不解决进程阻塞本质
  • Nginx 默认 proxy_read_timeout 是 60 秒,超时后主动断开,客户端收不到响应
  • MySQL 连接可能因 wait_timeout 中断,触发 PDOException: MySQL server has gone away

扫码登录这类场景该用伪长轮询而非真长连接

客户端每 1–2 秒发一次 GET 请求,服务端查 Redis,有结果立刻返回,无结果快速返回空 JSON(如 {"code": 0, "msg": "waiting"}),不挂起、不阻塞。

阅读全文
标签:PHPThinkPHP

本文共计1014个文字,预计阅读时间需要5分钟。

如何使用ThinkPHP高效实现长连接请求处理?

ThinkPHP 本身不支持真正意义上的长连接请求,所有长连接都需脱离 PHP-FPM 模式,改用 Swoole 或 Workerman 等常驻进程方案;在标准 Web 部署下,仅能依赖伪长轮询模拟。

为什么不能在控制器里用 sleep() 挂起请求

PHP-FPM 是同步阻塞模型,每个请求独占一个 worker 进程。写 sleep(5)while (!Redis::get($key)) { usleep(100000); } 会导致该 worker 被锁死,无法处理新请求。压测时很快出现超时、502、FPM 进程耗尽。

  • 即使加了 set_time_limit(0),也只延长脚本执行时间,不解决进程阻塞本质
  • Nginx 默认 proxy_read_timeout 是 60 秒,超时后主动断开,客户端收不到响应
  • MySQL 连接可能因 wait_timeout 中断,触发 PDOException: MySQL server has gone away

扫码登录这类场景该用伪长轮询而非真长连接

客户端每 1–2 秒发一次 GET 请求,服务端查 Redis,有结果立刻返回,无结果快速返回空 JSON(如 {"code": 0, "msg": "waiting"}),不挂起、不阻塞。

阅读全文
标签:PHPThinkPHP