从最早的同步阻塞直接 Fork 进程,到 Worker 进程池/线程池,再到现在的异步IO、协程,并发 IO 问题一直是服务器端编程中的技术难题。虽然,PHP 程序员因为有强大的 LAMP 框架,不需要了解太多这些底层的东西,也能解决大多数问题,但如果你想解决一些高级问题,你必须对这些有所了解。
在PHP中,有两大利器可以解决这些问题,即是Workerman和 Swoole 。
Workerman
workerman是一个高性能的PHP socket 服务器框架,workerman基于PHP多进程以及 libevent 事件轮询库,PHP开发者只要实现一两个接口,便可以开发出自己的网络应用,例如Rpc服务、聊天室服务器、手机游戏服务器等。
workerman的目标是让PHP开发者更容易的开发出基于 socket 的高性能的应用服务,而不用去了解PHP socket以及PHP多进程细节。 workerman本身是一个PHP多进程服务器框架,具有PHP进程管理以及socket通信的模块,所以不依赖php-fpm、nginx或者 apache 等这些容器便可以独立运行。
1、环境要求
Windows用户
Windows用户只能使用windows版本的Workerman(Workerman-for-win)。
1、需要PHP>=5.3.3,并配置好PHP的环境变量。
2、Windows版本的Workerman不依赖任何扩展。
3、安装使用以及注意事项参见这里。
Linux用户(含Mac OS)
Linux用户只能使用Linux版本的Workerman。
1、安装PHP>=5.3.3,并安装了pcntl、posix扩展
2、建议安装event或者libevent扩展,但不是必须的(注意event扩展需要PHP>=5.4)
Linux环境检查脚本
Linux用户可以运行以下脚本检查本地环境是否满足WorkerMan要求
curl -Ss | php
如果脚本中全部提示ok,则代表满足WorkerMan运行环境
(注意:检测脚本中没有检测event扩展或者libevent扩展,如果并发连接数大于1024建议安装event扩展或者libevent扩展,安装方法参见下一节)
关于WorkerMan依赖的扩展
1、pcntl扩展
pcntl扩展是PHP在Linux环境下进程控制的重要扩展,WorkerMan用到了其进程创建、信号控制、定时器、进程状态监控等特性。此扩展win平台不支持。
2、posix扩展
posix扩展使得PHP在Linux环境可以调用系统通过POSIX标准提供的接口。WorkerMan主要使用了其相关的接口实现了守护进程化、用户组控制等功能。此扩展win平台不支持。
3、libevent扩展 或者 Event扩展
libevent扩展(或者event扩展)使得PHP可以使用系统Epoll、Kqueue等高级事件处理机制,能够显著提高WorkerMan在高并发连接时CPU利用率。在高并发 长连接 相关应用中非常重要。libevent扩展(或者event扩展)不是必须的,如果没安装,则默认使用PHP原生Select事件处理机制。
2、安装
和nginx+PHP-FPM下的PHP应用程序一样,WorkerMan中的应用程序也需要一个入口文件,入口文件名没有要求,并且这个入口文件是以PHP Cli方式运行的。
1、任意位置建立项目目录
如 SimpleChat/
2、引入Workerman/Autoloader.php
3、选定协议
这里我们选定Text文本协议(WorkerMan中自定义的一个协议,格式为文本+换行)
(目前WorkerMan支持HTTP、Websocket、Text文本协议,如果需要使用其它协议,请参照协议一章开发自己的协议)
4、根据需要写入口启动脚本
如下:
3、实用案例
实例一、使用HTTP协议对外提供Web服务
实例二、使用WebSocket协议对外提供服务
实例三、直接使用 TCP 传输数据
实例四、定时器
实例5、异步任务
注意:
-
workerman不依赖apache或者nginx,只要PHP环境OK workerman就可以运行
-
workerman是命令行启动的,启动方式类似apache使用命令启动(一般网页空间无法使用workerman)
-
长连接必须加心跳,长连接长时间不通讯肯定会被防火墙干掉而断开
-
客户端和服务端协议一定要对应才能通讯,不要尝试在浏览器地址栏访问websocket协议端口,不要尝试用webscoket协议访问裸tcp协议端口,协议一定要对应
-
不要使用exit die语句,否则进程会退出,并显示WORKER EXIT UNEXPECTED错误。当然,进程退出了会立刻重启一个新的进程继续服务。如果需要返回,可以调用return
-
改代码要重启,workerman是常驻内存的框架,改代码要重启workerman才能看到新代码的效果
-
Worker::runAll()执行后将永久阻塞,也就是说位于Worker::runAll()后面的代码将不会被执行。所有Worker实例化应该都在Worker::runAll()前进行。
workerman官网:
Swoole
Swoole使 PHP 开发人员可以编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP,WebSocket 服务。Swoole 可以广泛应用于互联网、移动通信、企业软件、云计算、网络游戏、物联网(IOT)、车联网、智能家居等领域。 使用 PHP + Swoole 作为网络通信框架,可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
1、环境要求
-
仅支持 Linux,FreeBSD,MacOS,3类操作系统
-
Linux 内核版本 2.3.32 以上
-
PHP-5.3.10 以上版本,包括PHP7
-
gcc4.4 以上版本或者clang
-
cmake2.4+,编译为 libswoole.so 作为 C/C++ 库时需要使用 cmake
建议使用 Ubuntu14、CentOS7 或更高版本的操作系统
2、编译安装
Swoole扩展是按照PHP标准扩展构建的。使用phpize来生成编译检测脚本,./configure来做编译配置检测,make进行编译,make install进行安装。请下载releases版本的swoole,直接从github主干上拉取最新代码可能会编译不过。如果当前用户不是root,可能没有PHP安装目录的写权限,安装时需要sudo或者su。如果是在git分支上直接git pull更新代码,重新编译前务必要执行make clean
下载地址:
下载源代码包后,在终端进入源码目录,执行下面的命令进行编译和安装
编译安装成功后,修改php.ini加入
extension=swoole.so
通过php -m或phpinfo()来查看是否成功加载了swoole,如果没有可能是php.ini的路径不对,可以使用php -i |grep php.ini来定位到php.ini的绝对路径。
3、实用案例
案例一、创建TCP服务器
案例二、创建Web服务器
Http服务器只需要关注请求响应即可,所以只需要监听一个onRequest事件。当有新的Http请求进入就会触发此事件。事件 回调函数 有2个参数,一个是$ request对象 ,包含了请求的相关信息,如GET/POST请求的数据。
案例三、创建WebSocket服务器
WebSocket服务器是建立在Http服务器之上的长连接服务器,客户端首先会发送一个Http的请求与服务器进行握手。握手成功后会触发onOpen事件,表示连接已就绪,onOpen函数中可以得到$request对象,包含了Http握手的相关信息,如GET参数、Cookie、Http头信息等。
案例四、设置定时器
swoole提供了类似JavaScript的setInterval/setTimeout异步高精度定时器,粒度为毫秒级。使用也非常简单。
案例五、执行异步任务
在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。
Swoole提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。
注意:
-
不要在代码中执行sleep以及其他睡眠函数,这样会导致整个进程阻塞
-
exit/die是危险的,会导致worker进程退出
-
可通过register_shutdown_function来捕获致命错误,在进程异常退出时做一些清理工作
-
PHP代码中如果有异常抛出,必须在回调函数中进行try/catch捕获异常,否则会导致工作进程退出
-
swoole不支持set_exception_handler,必须使用try/catch方式处理异常
-
Worker进程不得共用同一个Redis或MySQL等网络服务客户端,Redis/MySQL创建连接的相关代码可以放到onWorkerStart回调函数中
-
异步程序要求代码中不得包含任何同步阻塞操作
-
异步与同步代码不能混用,一旦应用程序使用了任何同步阻塞的代码,程序即退化为同步模式
-
由于swoole是常驻内存的,所以加载类/函数定义的文件后不会释放。因此引入类/函数的php文件时必须要使用include_once或require_once,否会发生cannot redeclare function/class 的致命错误。
-
PHP守护进程与普通Web程序的变量生命周期、内存管理方式完全不同。请参考 swoole_server内存管理 页面。 编写swoole_server或其他常驻进程时需要特别注意。
-
进程隔离也是很多新手经常遇到的问题。修改了全局变量的值,为什么不生效,原因就是全局变量在不同的进程,内存空间是隔离的,所以无效。所以使用swoole开发Server程序需要了解进程隔离问题。
swoole官网:
Workerman和Swoole
workerman和swoole都是解决PHP复杂问题的利器,workerman是纯PHP开发的,而swoole是C语言开发的,所以在性能方面,如内存管理、数据结构、通信协议解析,swoole强于workerman。
外部依赖上workerman需要依赖很多额外的第三方PHP扩展来实现,局限性比较大,这些扩展并非是PHP官方维护的,维护性方面良莠不齐,而Swoole基本上无依赖,底层的代码全部可控。
功能上swoole提供的高级特性很多,比如SSL/TLS隧道加密、http2.0、异步mysql驱动、异步redis驱动、异步的http/websocket客户端、process、lock、atomic、table。另外Swoole 2.0内置了PHP原生协程的支持,PHP代码也可以使用类似于Go语言的协程来实现高并发的网络服务器。
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~