ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 2.2 swoole ## 简介 PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据库连接池,AsyncTask,消息队列,毫秒定时器,异步文件读写,异步DNS查询。 Swoole内置了Http/WebSocket服务器端/客户端、Http2.0服务器端。 ## 官网 [https://www.swoole.com](https://www.swoole.com) ## php-msf使用的swoole特性 我们在学习msf之前应该先了解swoole的各种特性,swoole的功能很多,各种使用姿势,本节主要介绍msf框架所使用的swoole主要特性。 ### 进程模型 msf框架使用了swoole的进程模式([更多模式的介绍](https://wiki.swoole.com/wiki/page/353.html)),进程模型示意图如下: ![进程模型](../images/swoole_process.png "进程模型") - 它是一个多进程模型框架,启动时创建2 + n + m个进程; - 2=1个master进程+1个manager进程 - master进程是Server实例的主进程,负责fork Manager进程及accept用户连接 - manager进程为管理进程,负责创建和管理所有的Worker和TaskWorker进程 - Reactor线程运行在master进程,实际运行epoll实例,用于accept客户端连接以及接收客户端数据 - Worker进程接受Reactor线程分配的用户请求,处理数据后返回给Reactor线程 - TaskWorker进程接受Worker投递的耗时任务,处理完成后执行异步回调函数,通知Worker进程 ### 执行流程 ![执行流程](../images/swoole执行流程.png "执行流程") ### 异步DNS 由于在发起http请求时,通常情况下URL中包含域名,而域名解析是一次UDP的网络请求,通过gethostbyname()函数进行域名解析是同步阻塞的,这与msf研发目标是相违背的,故我们需要异步查询DNS,swoole内置一个纯异步IO实现的异步DNS客户端: ```php swoole_async_dns_lookup("www.baidu.com", function($host, $ip){ echo "{$host} : {$ip}\n"; }); ``` [更多介绍](https://wiki.swoole.com/wiki/page/186.html) ### 异步Http Client 传统的curl请求是同步阻塞的,不能满足构建纯异步的Server需求,swoole内置异步的http client: ```php Swoole\Async::dnsLookup("www.baidu.com", function ($domainName, $ip) { $cli = new swoole_http_client($ip, 80); $cli->setHeaders([ 'Host' => $domainName, "User-Agent" => 'Chrome/49.0.2587.3', 'Accept' => 'text/html,application/xhtml+xml,application/xml', 'Accept-Encoding' => 'gzip', ]); $cli->get('/index.html', function ($cli) { echo "Length: " . strlen($cli->body) . "\n"; echo $cli->body; }); }); ``` [更多介绍](https://wiki.swoole.com/wiki/page/670.html) ### 异步Redis Client 我们常用的phpredis也是同步阻塞的,不能满足构建纯异步的Server需求,swoole内置异步的redis client: ```php $client = new swoole_redis; $client->connect('127.0.0.1', 6379, function (swoole_redis $client, $result) { if ($result === false) { echo "connect to redis server failed.\n" return; } $client->set('key', 'swoole', function (swoole_redis $client, $result) { var_dump($result); }); }); ``` [更多介绍](https://wiki.swoole.com/wiki/page/522.html) ### 异步MySQL Client 我们常用的pdo_mysql/mysqli,不能满足构建纯异步的Server需求,swoole内置异步的mysql client: ```php $db = new swoole_mysql; $server = array( 'host' => '192.168.56.102', 'port' => 3306, 'user' => 'test', 'password' => 'test', 'database' => 'test', 'charset' => 'utf8', //指定字符集 'timeout' => 2, // 可选:连接超时时间(非查询超时时间),默认为SW_MYSQL_CONNECT_TIMEOUT(1.0) ); $db->connect($server, function ($db, $r) { if ($r === false) { var_dump($db->connect_errno, $db->connect_error); die; } $sql = 'show tables'; $db->query($sql, function(swoole_mysql $db, $r) { if ($r === false) { var_dump($db->error, $db->errno); } elseif ($r === true ) { var_dump($db->affected_rows, $db->insert_id); } var_dump($r); $db->close(); }); }); ``` [更多介绍](https://wiki.swoole.com/wiki/page/517.html) ### Http Server 我们只需要简单的几行代码就能构建一个健壮的Http Server,因为swoole-1.7.7增加了内置Http服务器的支持,通过几行代码即可写出一个异步非阻塞多进程的Http服务器。 ```php $http = new swoole_http_server("127.0.0.1", 9501); $http->on('request', function ($request, $response) { $response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>"); }); $http->start() ``` [更多介绍](https://wiki.swoole.com/wiki/page/326.html) ### 异步毫秒定时器 msf框架内部的功能实现有基于异步毫秒定时器,比如协程调度,请求超时等等。 [更多介绍](https://wiki.swoole.com/wiki/page/244.html) ### 异步文件系统IO msf框架写日志是纯异步的IO,也就是说请求结束后,不需要等待日志写入成功就可以处理下一个请求。 [更多介绍](https://wiki.swoole.com/wiki/page/183.html) ### 进程管理 在swoole的进程模式下,我们还可以创建自定义的进程,比如msf框架在server启动时会创建config进程,用于全局配置创建与更新,同时收集server的所有worker运行状态。 [更多介绍](https://wiki.swoole.com/wiki/page/p-process.html)