Swoole 扩展安装与使用入门
Swoole 概述
Swoole 是面向生产环境的 PHP 异步网络通信引擎。使用纯 C 语言编写(Swoole 4 开始逐渐改为通过 C++ 编写),提供了 PHP 语言的异步多线程服务器、异步 TCP/UDP 网络客户端、异步 MySQL、异步 Redis、数据库连接池、AsyncTask、消息队列、毫秒定时器、异步文件读写、异步 DNS 查询。除了异步 IO 的支持之外,Swoole 为 PHP 多进程的模式设计了多个并发数据结构和 IPC 通信机制,可以大大简化多进程并发编程的工作。其中包括了并发原子计数器,并发 HashTable、Channel、Lock、进程间通信 IPC 等丰富的功能特性。
之前 PHP 一直被诟病的一个原因就是它是同步阻塞式语言,这在 Web 应用这种 IO 密集型的领域对于编写高并发高性能的应用而言,是一个重大阻碍。有了 Swoole 之后,PHP 开发人员可以轻松编写高性能的异步并发 TCP、UDP、Unix Socket、HTTP 以及 WebSocket 服务,从而使得 PHP 语言在异步 IO 和网络通信领域开疆拓土,并且有望在工业级技术方面与 Node.js 和 Go 语言展开角逐。从某种角度上说,Swoole 让 PHP 插上了异步的翅膀,让它飞得更高。
值得一提的是,Swoole 由中国的韩天峰创建并维护,目前已经以独立的开源项目形式进行运作和维护,关于 Swoole 的最新进展可以看下作者韩天峰的这篇文章:Swoole 2019 :化繁为简、破茧成蝶。
关于 Swoole 的官方中文文档可以看这里:https://wiki.swoole.com,本系列教程主要侧重于在 Laravel 框架中集成使用 Swoole 来构建高性能 Laravel 应用。
此外,如果想要更好的掌握 Swoole 的底层原理,需要具备以下知识储备:
多进程/多线程
- 了解 Linux 操作系统进程和线程的概念
- 了解 Linux 进程/线程切换调度的基本知识
- 了解进程间通信的基本知识,如管道、UnixSocket、消息队列、共享内存
SOCKET
- 了解 SOCKET 的基本操作如 accept/connect、send/recv、close、listen、bind
- 了解 SOCKET 的接收缓存区、发送缓存区、阻塞/非阻塞、超时等概念
IO复用
- 了解 select/poll/epoll
- 了解基于 select/epoll 实现的事件循环,Reactor 模型
- 了解可读事件、可写事件
TCP/IP网络协议
- 了解 TCP/IP 协议
- 了解 TCP、UDP 传输协议
调试工具
- 使用 gdb 调试 Linux 程序
- 使用 strace 跟踪进程的系统调用
- 使用 tcpdump 跟踪网络通信过程
- 其他 Linux 系统工具,如 ps、lsof、top、vmstat、netstat、sar、ss 等
注:关于这部分内容你可以网上搜索相应资源进行了解,也可以通过程序员内功修炼系列进行系统学习。
安装启用
Swoole 是 PHP 的一个扩展,可以通过 PHP 扩展的方式进行安装和启用。
本地安装
Laradock
在本地安装的话,以 Laradock 为例,需要在 laradock
目录下的 .env
中将下面两行配置值设置为 true
:
WORKSPACE_INSTALL_SWOOLE=true
PHP_FPM_INSTALL_SWOOLE=true
然后运行 docker-compose build php-fpm workspace
重新构建 Docker 容器,构建完成后重启这两个容器,进入 workspace
容器,运行 php -m
查看 Swoole 是否安装成功,如果扩展列表包含 swoole
则表示安装成功。
Windows/Mac
如果是本地 Windows/Mac 系统上安装的话,直接执行以下命令安装接口:
pecl install swoole
前提是 pecl
命令在系统路径中可用。然后运行 php -m
看到扩展列表包含 swoole
则表明安装成功。
线上安装
如果是在服务器安装的话,以 Ubuntu 系统为例,通过执行下列命令安装即可:
pecl install swoole
然后通过 php -i | grep php.ini
定位 php.ini
文件所在位置,并打开该配置文件,在文件末尾追加如下内容:
[swoole]
extension=swoole.so
保存并退出,在终端运行 php -m
,如果看到扩展里包含 swoole
,说明安装启用成功。
注:以上服务器安装方式也适用于 Homestead 和其他环境 Ubuntu 系统。
测试 Swoole
下面我们基于 Swoole 编写两个简单的功能来测试 Swoole 是否可以正常工作。
HTTP 服务器
首先我们通过 Swoole 编写一个简单的 HTTP 服务器,在测试目录下创建一个 http_server.php
文件,编写文件代码如下:
<?php
// 表明服务器启动后监听本地 9051 端口
$server = new swoole_http_server('127.0.0.1', 9501);
// 服务器启动时返回响应
$server->on("start", function ($server) {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
});
// 向服务器发送请求时返回响应
// 可以获取请求参数,也可以设置响应头和响应内容
$server->on("request", function ($request, $response) {
$response->header("Content-Type", "text/plain");
$response->end("Hello World\n");
});
// 启动 HTTP 服务器
$server->start();
这样,一个最基本的 HTTP 服务器就完成了,其工作原理和工业级的 Apache 和 Nginx 服务器类似,只不过提供的是最简单的服务器监听和响应功能罢了,我们在终端启用这个服务器:
这样,表示服务器已经启动并且在监听请求了,到浏览器中访问 http://127.0.0.1:9501
,即可获取服务器输出响应内容:
TCP 服务器和客户端
接下来,我们通过 Swoole 及其协程特性实现一个简单的 TCP 服务器和客户端,TCP 协议需要双方通过三次握手建立连接后才能进行通信,所以是一种可靠的协议,常见的聊天室应用就是基于 TCP 协议传输内容。我们还是在前面的测试目录下创建一个 tcp_server.php
文件用于编写 TCP 服务端代码:
<?php
namespace Swoole;
// 监听本地 9503 端口,等待客户端请求
$server = new Server("127.0.0.1", 9503);
// 建立连接时输出
$server->on('connect', function ($serv, $fd){
echo "Client:Connect.\n";
});
// 接收消息时返回内容
$server->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, 'Swoole: '.$data);
$serv->close($fd);
});
// 连接关闭时输出
$server->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
// 启动 TCP 服务器
$server->start();
然后在该目录下创建一个 tcp_client.php
文件用于编写 TCP 客户端代码:
<?php
namespace Swoole;
// Swoole4以后通过协程来实现异步通信
go(function () {
$client = new Coroutine\Client(SWOOLE_SOCK_TCP);
// 尝试与指定 TCP 服务端建立连接(IP和端口号需要与服务端保持一致,超时时间为0.5秒)
if ($client->connect("127.0.0.1", 9503, 0.5)) {
// 建立连接后发送内容
$client->send("hello world\n");
// 打印接收到的消息
echo $client->recv();
// 关闭连接
$client->close();
} else {
echo "connect failed.";
}
});
这样,一个最基本的 TCP 服务端和客户端程序就编写完成了,在终端先启动 TCP 服务端:
php tcp_server.php
然后新开启一个终端窗口,启动 TCP 客户端:
输出从 TCP 服务端接收到消息后 TCP 客户端退出,此时服务端也会打印连接建立和断开的日志消息:
客户端退出后,服务端依然处理监听状态,等待下一个请求。
好了,以上就是今天要给大家介绍的 Swoole 安装及入门教程,后面我们将结合 Laravel 应用实例逐步给大家介绍更多的 Swoole 特性及使用方法,以及如何基于 Swoole 构建高性能的 Laravel 应用。
39 Comments
这怎么和laravel整合啊 laravel和Socket 通讯好像还是echo比较好吧 这个是自己单独重写一套系统吧!
自然是可以
高端啊
laravel 来做swoole 还是有点吃力,没办法发挥100%的能力,比如协程这些,还是基于swoole的框架 easyswoole sowft ds这些来做好一些
laradock 怎么将端口映射到宿主机上访问?
不需要映射 可以直接访问 因为 Docker 是以进程方式运行的 不是独立的虚拟机
使用了这个调试工具debugbar不能用了呢?
学院君,你好,请问下我用的是,laradock ,在 workspace 容器 里,执行
php http_server.php
,当时在宿主机:访问 http://127.0.0.1:9501/ 没有逾期的:Hello word。只有:你的9501端口没有从 Docker 容器中 expose 出来吧 这种就直接本地宿主机启动得了
docker-compose build php-fpm workspace 报错如下,(这个搞不懂怎么排错,求大佬支援):
ERROR: Service 'workspace' failed to build: The command '/bin/sh -c if [ ${INSTALL_SWOOLE} = true ]; then if [ $(php -r "echo PHP_MAJOR_VERSION;") = "5" ]; then pecl -q install swoole-2.0.10; else if [ $(php -r "echo PHP_MINOR_VERSION;") = "0" ]; then pecl install swoole-2.2.0; else pecl install swoole; fi fi && echo "extension=swoole.so" >> /etc/php/${LARADOCK_PHP_VERSION}/mods-available/swoole.ini && ln -s /etc/php/${LARADOCK_PHP_VERSION}/mods-available/swoole.ini /etc/php/${LARADOCK_PHP_VERSION}/cli/conf.d/20-swoole.ini && php -m | grep -q 'swoole' ;fi' returned a non-zero code: 1
求大佬支援