您的位置 首页 php

「服务器」解决PHP高级问题的两大利器

从最早的同步阻塞直接 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、异步任务

任务进程服务端

异步任务客户端

注意:

  1. workerman不依赖apache或者nginx,只要PHP环境OK workerman就可以运行

  2. workerman是命令行启动的,启动方式类似apache使用命令启动(一般网页空间无法使用workerman)

  3. 长连接必须加心跳,长连接长时间不通讯肯定会被防火墙干掉而断开

  4. 客户端和服务端协议一定要对应才能通讯,不要尝试在浏览器地址栏访问websocket协议端口,不要尝试用webscoket协议访问裸tcp协议端口,协议一定要对应

  5. 不要使用exit die语句,否则进程会退出,并显示WORKER EXIT UNEXPECTED错误。当然,进程退出了会立刻重启一个新的进程继续服务。如果需要返回,可以调用return

  6. 改代码要重启,workerman是常驻内存的框架,改代码要重启workerman才能看到新代码的效果

  7. 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语言的协程来实现高并发的网络服务器。

文章来源:智云一二三科技

文章标题:「服务器」解决PHP高级问题的两大利器

文章地址:https://www.zhihuclub.com/79572.shtml

关于作者: 智云科技

热门文章

网站地图