基于 Swoole 构建高性能 Laravel 应用系列 —— 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 应用。

学院君 has written 1083 articles

Laravel学院院长,终身学习者

积分:137437 等级:P12 职业:手艺人 城市:杭州

4 条回复

  1. sinchan1986 sinchan1986 says:

    laravel 来做swoole 还是有点吃力,没办法发挥100%的能力,比如协程这些,还是基于swoole的框架 easyswoole sowft ds这些来做好一些

  2. 这怎么和laravel整合啊 laravel和Socket 通讯好像还是echo比较好吧 这个是自己单独重写一套系统吧!

登录后才能进行评论,立即登录?