初识 Swoole
前言
在之前的教程当中我们已经了解到了php的几种运行模式:
CGI
通用网关接口(Common Gateway Interface)Fast-CGI
是cgi
的升级版本,用PHP-FPM(FastCGI Process Manager)
即fast-cgi
进程管理器mod
以模块的形式集成进Apache
中,接受Apache
提供的.php文件,并进行解析。CLI
命令行模式,直接使用PHP
去执行.php文件时便是此模式。
尽管 CLI
模式可以完成更多有趣和强大的功能,但大多数php程序员很少使用 CLI
模式。
起源
Swoole是Rango在2010年底,因为公司业务需要自己实现一个Tcp Socket Server 实现SMT P协议接收数据,但是在当时PHP在这个领域几乎是一片空白,所以Rango自己学习,最终完成了需求;随后便开源了此套系统,希望能帮助其他PHPer解决在这个领域的问题,让PHP从单纯的Web开发扩展到更大的空间。
项目起源
Swoole 项目最初的想法是来自于之前所做的一个企业软件项目。当时大概是2010年底,公司产品有一个需求是用户可以任意生成一个 email 地址,然后其他用户可以向这个email发邮件,后台能实时将邮件内容解析成数据,并主动通知用户。当时项目使用PHP开发的,在实现这个需求时遇到了难题,PHP只能依赖其他的STMP服务器,通过pop3协议定时查收新邮件来完成,这样就不是实时的。如果要实现的实时系统必须自己写一个TCP Socket Server实现SMTP协议接收数据。当时PHP在这个领域几乎是空白,没有一套成熟的网络通信框架。为了实现需求,我从socket学起到TCP/IP、IO复用、libevent、多进程,最后终于实现了这套程序。做完这个项目后我就想把这套程序开源出来,希望能帮助其他PHPer解决在这个领域的难题。如果能有这样一个框架,那么PHP就能从单纯地做一个Web网站延伸到更大的空间。还有一个重要的原因是PHP程序的性能问题,我最早是学Java出身的,工作后才转行成为一名PHP程序员。在使用PHP开发程序的过程中,我一直在思考的问题 PHP 和 Java 比最大的优势是什么?简单高效, PHP 在请求完成之后会释放所有资源和内存,无须担心内存泄漏。代码的质量无论高低一样运行的很流畅。但同时这也是 PHP 致命的缺点。一旦请求数量上升,并发很高的时候,快速创建资源,又马上释放,使得 PHP 程序运行效率急剧下降。另外一旦项目的功能的越来越复杂,代码增多后,对于 PHP 也会是灾难。这也是 PHP 的框架为什么没有被 PHP 程序员广泛接受,而 Java 不存在这个问题。再好的框架也会被这种低效的方式拖累,导致系统变慢。所以想到了使用 PHP 来开发 PHP 的应用服务器,让 PHP 的代码加载到内存后,拥有更长的生命周期,这样建立的数据库连接和其他大的对象,不被释放。每次请求只需要处理很少的代码,而这些代码只在第一次运行时,被 PHP 解析器编译,驻留内存。另外,之前 PHP 不能实现的,对象持久化、数据库连接池,缓存连接池都可以实现。系统的运行效率会大大提高。
经过一段时间研究,目前已经初步得到实现。使用 PHP 本身编写出 HTTP 服务器,以独立服务器方式运行,单个程序页面 ( 有对象生成,数据库连接、 smarty 模板操作 ) 的执行时间由原来的 0.0x 秒,下降到 0.00x 秒。使用 Apache AB 并发 100 测试。比传统 LAMP 方式, Request per Second 高出至少 10 倍。在我的测试机上 (Ubuntu10.04 Inter Core E5300 + 2G 内存 ) , Apache 只跑到 83RPS 。 Swoole Server 可以跑到 1150 多 RPS。
这个项目就是Swoole的雏形。这个版本一直持续维护了2年多,在这个过程中逐步有了一些经验积累,对这套技术方案的存在问题有了更深入的理解,比如性能差、限制较多无法直接调用操作系统接口、内存管理效率低下。
入职腾讯
2011年底我入职腾讯,负责朋友网的PHP平台开发工作。惊奇地发现朋友网的同事不光这样想了,他们直接做到了。朋友网团队已经在生产环境中使用了这套方案。朋友网有三架马车,第一个是PWS,这是一个纯PHP编写的WebServer,朋友网线上有600多台服务器运行在PWS上,完全没有使用Apache、PHP-FPM之类的程序。第二个是SAPS,这是使用纯PHP开发的一个分布式队列,当时大概由150台服务器的集群在跑,很多图片裁剪、头像处理、消息同时、数据同步等逻辑全部使用了SAPS做逻辑异步化。第三个是PSF,这是一个PHP实现的Server框架,朋友网很多逻辑层的服务器都是基于PSF实现的。大概有300台左右的集群在运行PSF服务器程序。在朋友网的这段时间,我学到了很多Linux底层、网络通信的知识,积累了很多大型集群高并发环境的网络通信跟踪、调试经验,为开发Swoole打下了一个很好的基础。开发Swoole
在这期间也学习了解到了Node.js、Golang这些优秀的技术方案,得到了更多灵感。在2012年的时候就有了新的想法,决定使用C语言重新实现一个性能更强、功能更强大的版本。这就是现在的Swoole扩展。现在Swoole已经被很多PHP技术团队用于实际项目的开发工作,国内国外都有。国内知名的有百度订单中心、百度地图、腾讯QQ公众号和企业QQ、战旗直播、360、当当网、穷游等。另外还有很多物联网、硬件、游戏项目也在使用Swoole 。另外基于Swoole的开源框架也越来越多,比如TSF、Blink、swPromise 等等,在Github上也能找到很多Swoole相关的项目和代码。
名字由来
Swoole这个名字不是一个英文单词,是由我创造的一个音近字。我最早想到的名字是叫做sword-server
,寓意是为广大PHPer创造一把锋利的剑,后来联想到swoole
。
现在
随着Swoole进入4.0时代,原2.0时期协程的各种各样的坑,在4.0都得到了解决。 如今的Swoole可以说是真正好用可靠的PHP异步网络引擎。
2018年7月Rango辞去工作,组织了全职的研发团队来开发 Swoole 内核、组件和工具链。在文档、测试、社区运营方面也会投入更多资源。本段来源
Swoole 能做什么
以下内容来源于Swoole官方文档
Swoole 是使用 C
和 C++
语言编写的PHP扩展, 内置了异步非阻塞、多线程的网络IO服务器,PHP程序员仅需处理事件回调即可,无需关心底层。
同时Swoole也提供了许多非常多的内置功能如:
- PHP语言的异步多线程服务器
- 异步TCP/UDP网络客户端
- 异步MySQL
- 异步Redis
- 数据库连接池
- AsyncTask
- 消息队列
- 毫秒定时器
- 异步文件读写
- 异步DNS查询
- Http/WebSocket服务器端/客户端
- Http2.0服务器端/客户端
与大家熟知的 Workerman
框架不同,Swoole更像是一个基础库给了开发者一把无比锋利的宝剑,可以按照自己想要的方法去使用。
Swoole绝大部分功能都只能运行在 CLI
模式下,也正因为此开发者可以完全的掌控Server的一切,与传统的 php-fpm
模式不同,Swoole需要开发者自行接管各种相关事件,和管理变量的生命周期等。
与传统Web开发的区别
我们知道 php-fpm
是 fast-cgi
运行模式的进程管理器,当启动Server时 php-fpm
会预创建若干个 fast-cgi
处理进程; 每当请求到达 Nginx
时 Nginx
检查到请求的是.php文件时,就将请求转发给 php-fpm
Server 然后由 php-fpm
交给某个空闲的进程处理,当处理完成后由 php-fpm
返回给 Nginx
然后由 Nginx
响应给用户。
传统PHP开发者几乎无需关注这其中发生的过程甚至根本不了解,正所谓成也萧何败萧何,一方面虽然降低了开发者入门的门槛但另一方面也使得大量的PHP开发者几乎不了解也不懂的真正的服务端开发。
而 SwooleServer
则是相当于取代了 php-fpm
作为管理器的位置, 由于Swoole 是运行在 CLI
模式下, 所以可以常驻运行和以守护进程运行, 但也正因为如此,也需要开发者自行处理变量的销毁及各种异常和超时的处理。