PHP 这么拉?长连接都搞不了?说说 PHP 的 socket 编程

PHP 这么拉?长连接都搞不了?说说 PHP 的 socket 编程

💡 原文中文,约4900字,阅读约需12分钟。
📝

内容提要

PHP的发展历史与其他编程语言不同,早期用于生成动态内容的Web页面。PHP支持多种运行模式,包括CGI、FastCGI和CLI。Workerman是一个基于PHP socket的高性能应用容器,实现高并发长连接。根据业务场景和团队实际情况选择合适的PHP解决方案可以获得不错的效果和开发维护成本优势。

🔎

延伸解读

误解从何而来:历史包袱与 LAMP 的刻板印象

文章指出,PHP 常被贴上“简单且慢”的标签,甚至被认为无法独立创建服务或处理长连接。这种误解与 PHP 的发展历史密切相关:它最初是为生成动态网页而设计的 CGI 工具集,后来才逐步完善为现代编程语言。而 LAMP 架构的流行,让许多人误以为 PHP 只能依附于 Apache 或 Nginx 运行,忽略了它其实支持多种运行模式。

CGI 与 FastCGI:性能提升但长连接仍受限

文章对比了 PHP 的几种运行模式。CGI 模式下,每次请求都会 fork 子进程并在处理后销毁,虽然简单且无内存泄漏之虞,但频繁创建销毁进程导致性能开销大,也无法利用长连接或池化技术。FastCGI 通过预创建常驻进程减少了进程开销,PHP-FPM 是其实现,但 Web 服务器与 FPM 之间仍是短连接,因此这种模式依然不支持与客户端的长连接。

CLI 模式与 socket 编程:长连接的自然路径

文章强调,CLI 模式才是 PHP 实现长连接的关键。在这种模式下,PHP 通过解释器直接运行,支持系统调用和常驻内存,可以像其他语言一样进行 socket 网络编程。文章给出了使用 sockets 扩展实现 TCP 长连接服务的示例,并提到 stream 系列函数也能处理 socket。这打破了“PHP 不能做长连接”的固有印象。

Workerman 的实践:多进程与 IO 多路复用

文章以 Workerman 为例,说明基于 PHP socket 的 CLI 应用容器如何实现高并发长连接。Workerman 结合 IO 多路复用和多进程,并讨论了 SO_REUSEPORT 选项对惊群问题的影响:默认不开启时,主进程创建 socket 后 fork 子进程,请求到来会唤醒所有子进程但只有一个能 accept,造成资源浪费;开启后各子进程独立创建 socket,由操作系统负载均衡唤醒,避免了惊群。

❓

Q&A

PHP的主要误解是什么?

很多人认为PHP简单且慢,无法独立创建服务,只能与Apache或Nginx配合使用。

PHP支持哪些运行模式?

PHP主要支持CGI模式、CLI模式和FastCGI模式。

什么是Workerman,它的主要功能是什么?

Workerman是一个基于PHP socket的高性能应用容器,支持高并发长连接。

CGI模式的主要缺点是什么?

CGI模式每次处理请求都需要重新创建和销毁进程,性能开销较大,无法支持长连接。

PHP的CLI模式与其他模式有什么不同?

CLI模式直接使用PHP解释器运行代码,支持常见的系统调用,适合实现socket网络编程和长连接。

如何选择合适的PHP解决方案?

根据业务场景和团队实际情况选择合适的PHP解决方案,可以降低开发和维护成本。

🏷️

标签

➡️

继续阅读