├── images ├── 1.png └── 2.png ├── logs └── 2025-05.md ├── v4.6.md ├── README.md ├── TDD.md ├── v4.5.md ├── HOW_TO_CONTRIBUTE.md ├── RELEASE_MANAGE.md ├── v6.md ├── rpc.md ├── v5.md └── ROLE.md /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoole/rfc/HEAD/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swoole/rfc/HEAD/images/2.png -------------------------------------------------------------------------------- /logs/2025-05.md: -------------------------------------------------------------------------------- 1 | # 2025.05 2 | 3 | 1. 增加更多 `core tests` 单元测试,将覆盖率提升至 `80%` 4 | 2. 重构底层代码和 `API` 5 | 3. 使用 `clang-tidy` 静态分析工具,优化 `C++` 代码 6 | 7 | -------------------------------------------------------------------------------- /v4.6.md: -------------------------------------------------------------------------------- 1 | 依赖 2 | --- 3 | * 不再支持`32`系统 4 | * 不再支持`PHP-7.1` 5 | * 增加对`PHP-8`的支持 6 | 7 | 配置 8 | ---- 9 | * `Co\Run`时默认开启`HOOK` 10 | 11 | 移除 12 | ---- 13 | * 废弃在`shutdown`函数中自动添加`Event::wait()`的逻辑,必须显式调用`Co\Run`等容器,或者添加`Event::wait()` 14 | 15 | 时间 16 | --- 17 | * 预计在`PHP-8`正式版发布后的一个月内发布 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rfc-chinese 2 | 3 | 提案 4 | ---- 5 | * 提交`issue`发起提案,初始状态标记为`草案`,其他用户可以在该`issue`下发起讨论 6 | * 提案者可以根据社区用户的讨论,多次重新修订提案内容 7 | * 草案由 Swoole 开发组讨论,决定`接受`或`拒绝`,拒绝会给出拒绝的原因和理由,并`Close`该`Issue` 8 | * 草案被接受后,标记为`已接受`,成为正式的`RFC`提案 9 | * 开发者进入开发阶段,完成后在`swoole-src`发起`pull request` 10 | * 该`pr`需要经过多次`review`,并最终被`merge`,该提案标记为`已实现` 11 | * 该`pr`未能通过`code review`,没有被`merge`,该提案被标记为`未实现` 12 | * 接受并最终实现的提案按照给予`RFC-XXXX`唯一编号 13 | 14 | 分类 15 | ---- 16 | 按照提案的类型,我们将提案分成`3`类 17 | * `内核`,针对`Swoole`内核技术特性进行的新增、改进、移除操作 18 | * `类库`,在`Swoole`之上使用`PHP`实现的功能、工具、框架 19 | * `社区`,包括社区管理、文档、测试、会议等其他非技术类提案 20 | 21 | 投票 22 | ---- 23 | * 对草案或`RFC`提案的`issue`主题点击 👍 表示赞同,其他表情为不赞同 24 | 25 | 建议 26 | ---- 27 | * 请尽可能给出伪代码作为演示 28 | * 请注明影响的版本,`1.0`:异步回调版本,`2.0`:协程版本 29 | * 请务必详细描述整个提案,使开发者可以快速了解这个提案的目的和作用 30 | 31 | 参考 32 | 33 | -------------------------------------------------------------------------------- /TDD.md: -------------------------------------------------------------------------------- 1 | 测试驱动开发(`TDD`)是一种软件开发实践,它要求开发人员在编写实际代码之前先编写测试用例。这种方法有助于提高代码质量和开发效率。以下是一些 TDD 的主要好处: 2 | 3 | 1. **提高代码质量**:通过在编码之前编写测试用例,开发人员在实现功能时能够及时发现潜在的问题,测试用例可以清晰地定义需求,使团队成员更加明确功能要求。 4 | 2. **增强设计灵活**:由于有大量自动化测试,开发人员能够随时进行重构而不怕引入新bug, TDD 强调小步迭代,这促进了代码的模块化和解耦设计。 5 | 3. **促进文档化**:测试用例本身就是一种文档,它描述了代码的预期行为,使其他开发人员理解代码变得容易。开发人员可以依靠测试用例而不是复杂的外部文档来了解系统的期望行为。 6 | 4. **增强团队协作**:团队成员可以通过阅读测试用例来更好地理解项目的业务逻辑和功能。TDD 可以帮助团队保持代码的一致性,因为每个新功能都是基于现有的测试用例实现的。 7 | 5. **提高开发效率**:有助于降低调试和错误修复的时间,因为问题在早期被发现并且定位明确。 8 | 6. **减少不必要的功能开发**:由于测试用例引导设计,开发人员能够更专注于实现真正需要的功能,避免功能膨胀。 9 | 6. **提升开发者信心**:自动化测试提供了快速反馈,使开发人员在提交代码时更有信心。经过充分测试的代码发布时,bug 和问题的风险显著降低。 10 | 11 | 由于`Swoole`已经是一个拥有长达十几年历史开源项目了,已经没有重大的新增和变更,项目已经入了长尾维护期。 12 | 为了让`Swoole`项目能够持续保持进化,获得更长的生命周期,而不是逐渐落入历史的尘埃中。 13 | 我们需要一个行之有效的办法持续地提升项目的质量和稳定性,解决存在的历史包袱和错误设计。 14 | `TDD`是一个非常好的方法,我们将更多的时间和精力放在测试系统的设计、开发编写工作之上,包括: 15 | 16 | 1. 增加 `linux arm`平台测试 17 | 2. 增加 `macOS` 平台的自动化测试 18 | 3. 增加 `php unit tests` 覆盖率统计系统 19 | 4. 增加更多 `core tests`,使得覆盖率达到 `90%` 以上 20 | 21 | 在这个过程中发现并解决一些历史包袱,逐步进行重构,然后提高软件的代码质量、`API` 设计、代码复用性。 22 | -------------------------------------------------------------------------------- /v4.5.md: -------------------------------------------------------------------------------- 1 | Swoole 4.5 2 | ======= 3 | 4 | > 本文件将 [#34](https://github.com/swoole/rfc-chinese/issues/34) 号提案社区内广泛达成一致的内容进行归纳 5 | 6 | 目标: 7 | ----- 8 | 1. 纯粹协程化 9 | 2. 减少历史包袱,提升稳定性 10 | 3. 降低复杂度,减少不必要的选项 11 | 12 | 13 | 删除异步客户端 14 | ----- 15 | * 删除 异步`Swoole\Client`、`Swoole\Http\Client`、`Swoole\MySQL`、`Swoole\Redis` 4个模块。 16 | 17 | 18 | 删除对 FPM 的支持 19 | ------ 20 | > 此条目现在仍然存疑 21 | 22 | * 删除 同步`Swoole\Client` 23 | * 仅在`Cli`模式下启用`Swoole` 24 | 25 | 删除 Server 回调 26 | ----- 27 | * 删除 `onBufferEmpty` 28 | * 删除 `onBufferFull` 29 | 30 | 全新 Coroutine\Server 31 | ----- 32 | * 实现一个全新的,针对协程而设计,区别于`Swoole\Server`的 33 | 34 | #### 原型 35 | 36 | ```php 37 | $server = Coroutine::listen('tcp://127.0.0.1:9501', ['backlog' => 128, 'ssl_key_file' => '', 'open_length_check']); 38 | 39 | while ($conn = $server->accept()) { 40 | // 每接收到一个请求, 就创建一个协程去并发地处理它 41 | go (function () use ($conn) { 42 | // 打个招呼 43 | $conn->send(tcp_pack('Hello~')); 44 | // 先接收TCP包头长度的数据, 解析包长数据, 再接收包长长度的主体数据 45 | $data = $conn->recv(tcp_length($conn->recv(tcp_type_length()))); 46 | // 打包后原封不动地发回去 47 | $conn->send(tcp_pack($data)); 48 | // 开始循环接收, 直到超时或者对方关闭了连接 49 | while ($len = $conn->recv(tcp_type_length(), 1)) { 50 | $data = $conn->recv($len); 51 | echo "{$data}\n"; 52 | } 53 | // 退出循环体就关闭了 54 | $conn->close(); 55 | }); 56 | } 57 | ``` 58 | 59 | 60 | 其他杂项 61 | ---- 62 | * 删除 `Swoole\Serialize` 63 | -------------------------------------------------------------------------------- /HOW_TO_CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | 如何参与贡献 Swoole 开源项目 2 | ===== 3 | 4 | 技能需求 5 | ---- 6 | * `C++11`编程 7 | * 了解`Linux`系统相关`API`知识,如`epoll`、`socket`、`fork`、`pthread`,具备`Unix`环境编程能力 8 | * 了解`PHP` `ZendVM`的基本原理,了解`php-src` 9 | 10 | 安装软件 11 | ---- 12 | ```php 13 | sudo apt install php-dev gcc g++ cmake autoconf curl openssl 14 | ``` 15 | 16 | 克隆项目 17 | ---- 18 | 建议在`github`上`fork` `swoole-src` 到个人空间,然后`git clone`到本地 19 | 20 | ```shell 21 | cd ~/workspace/ 22 | git@github.com:{your_name}/swoole-src.git 23 | cd swoole-src 24 | ``` 25 | 26 | 开发环境 27 | ---- 28 | * `Linux`环境,建议使用 `Ubuntu 18/20`,`Windows`环境可使用`WSL2`或`虚拟机` 29 | * `C++11`编译器,建议使用`g++` 30 | * `IDE`:请使用`Eclipse CDT`,不建议使用`VIM`和`Emacs`这样的本文编辑器 31 | * 建议使用宽屏显示器,分辨率大于`1920x1080` 32 | 33 | 编码风格 34 | ----- 35 | * 遵循`Google C++ Style`规范 36 | * 请使用`clang-format` (`v9`或更高)工具格式化代码 37 | * 单行字符宽度调整为`120`,原因是在现代大屏幕显示器上,`Unix`传统的`80`宽度太小了,只占用到了`50%`左右屏幕,在屏幕上会留下大量空白区域,利用率不足。调整到`120`宽度,在`Eclipse`等`IDE`工具中,左侧是工程视图、右侧是类/函数结构视图,中间区域是代码编辑区,可以最大化利用显示器所有区域 38 | * 缩进从`2`空格调整为`4`空格,原因是`2`空格,辨识度较低,带来了不必要的心智负担,调整到`4`空格,会更加清晰 39 | 40 | 41 | #### 新建工程 42 | 在`Eclipse`中创建`C++`工程,目录使用克隆好的`swoole-src` 43 | 44 | #### 配置 IDE 45 | 配置工程的`include`路径,注意需要同时配置`C`和`C++`相关,将`php`头文件目录设置到`include`路径中。例如: 46 | 47 | * `/usr/local/include/php` 48 | * `/usr/local/include/php/main` 49 | * `/usr/local/include/php/TSRM` 50 | * `/usr/local/include/php/Zend` 51 | 52 | ![include路径](images/1.png) 53 | 54 | 55 | 配置工程的预定义宏,加入`HAVE_CONFIG_H` 56 | 57 | ![宏](images/2.png) 58 | 59 | #### 构建工程 60 | ```shell 61 | cd ~/workspace/swoole-src 62 | phpize 63 | ./configure 64 | make -j 8 65 | suod make install 66 | ``` 67 | 68 | #### 加载扩展 69 | 修改`php.ini`在末尾加入`swoole.so` 70 | 71 | 项目开发 72 | --- 73 | 修改`swoole-src`下的`.h`和`.cc`源文件,重新编译安装,编写测试脚本,验证是否生效。 74 | 75 | #### 目录结构 76 | 77 | * `src/` : 与`php`无关的内核模块源文件 78 | * `include/` : 头文件 79 | * `core-tests` : 内核测试文件,基于`googletest` 80 | * `tests` : `PHP`测试文件 81 | * `examples` : 示例文件 82 | * `swoole_*.cc` : `PHP`扩展相关源文件 83 | -------------------------------------------------------------------------------- /RELEASE_MANAGE.md: -------------------------------------------------------------------------------- 1 | # Swoole 版本更新手册 2 | 3 | ## 主要步骤 4 | 5 | - 写更新日志, 更新日志需要增加 library 的 (参考以前的更新日志格式, 从上到下分为新特性, 增强, 修复, 内核, PHP 程序员不关心的部分, 可以写入内核分类, 内核组无意义的小提交可以忽略, 但是外部贡献的必须写, 用于激励贡献者) 6 | - 使用 grammarly 插件检查英文的更新日志是否有语法错误 7 | - 修改 package.xml, 一定要更新版本号和日志内容 8 | - 重复检查版本号信息是否正确无误 (在打包时已有脚本自动检测) 9 | - 确保 library 是最新的, 并且位于 swoole-src 根目录下 10 | - 确保 library 没有未提交的内容, 打包时需要依据 git-hash 记录位置 (如果打包自动生成的代码导致了产生未提交的内容, 提交到 github 后重新来一遍, 提交内容一般为"Sync to Swoole-vX.y.z", 可以参考以前的提交) 11 | - 确保 build-library.php 中, 关于 library 的源码文件列表是完整的 (由于无法实施 autoload, 此步骤必须手动完成, 因为源码文件的顺序存在依赖关系) 12 | - 运行 tools/pecl-package.php 尝试进行打包, 脚本会根据 package.xml 的版本信息自动修改源码中的版本信息, 脚本还会运行多个检查修复程序: 13 | - 更新错误码, 常量等 14 | - 检查 arginfo/parse_paramaters 定义的正确性 15 | - 更新 library 代码到 php_swoole_library.h 16 | - 单元测试文件的检查和格式修复 17 | - 更新 package.xml 里的文件列表 18 | - 更新 package.xml 的打包时间 19 | - 打包时, 产生 warning 可能是正常的, 程序会告诉你源文件里的版本号是旧的, 会被替换成新的, 不放心可以再打包一次, 就没有 warning 了 20 | - 打包后, 本地检查是否能编译成功 (线上会自动执行打包步骤, 所以缺少参考价值), 采用多种编译方式: 21 | - 普通流程编译 (phpize, configure, make...) 22 | - PECL 编译 (pecl install swoole-x.y.z.tgz) 23 | - 有开关宏相关的改动注意检查 (如有编译有 ZLIB 和没有 ZLIB 的情况) 24 | - 检查是否有编译警告, macos(clang) 和 线上 (gcc) 25 | - 检查安装后 php --ri swoole 显示的信息是否正确 (尤其注意版本号) 26 | - git commit, 提交信息为 "Update version for Swoole x.y.x", 可以参考以前的提交, 都是统一的格式 27 | - 推送到多个分支进行单元测试, 查看是否能够通过 (不要提交到 master) 28 | - travis 分支普通测试 29 | - alpine 分支 musl 测试 30 | - valgrind 分支内存测试 (以没有 MEM 错误为准, 不一定能通过) (大概 50 分钟一次, 不一定能跑完) 31 | - coverity_scan 分支Bug静态分析测试 32 | - NTS 和 ZTS 版本, ubuntu 和 linux 等 (较难验证, 偶尔 ZTS 会有编译问题) 33 | - travis 通过了以后, 再推送到 master (否则你不得不使用`--force`重置以保证我们有干净的 git log, 但这样可能会破坏其他维护者的 git 时间线) 34 | - 进入 github releases 页面, 发布新版本, 两个标题都是 vX.y.z 的格式, 把 package.xml 的更新内容帖进去, 使用 preview 查看是否正确, 每一个#和每一个@都必须是蓝色高亮的, 否则就是存在错误 35 | - 可以稍作观察, 再次确认无误后进入 pecl 官网发布压缩包 (由于 pecl 系统比较复杂, 发错了再删除可能有点风险) 36 | - 发完版本第一个提交最好是改成下个版本的 dev (可使用 [next-version.php](https://github.com/swoole/swoole-src/blob/master/tools/next-version.php) 脚本) 37 | - 将更新日志翻译到中文, 同步到 [wiki.swoole.com](https://wiki.swoole.com) 38 | 39 | ## 其他 40 | 41 | - 如果底层 API 变动, 需要更新 [async](https://github.com/swoole/ext-async)/[postgresql](https://github.com/swoole/ext-postgresql) 扩展 42 | - 尽可能将修复补丁同步到 lts 分支(比如现在是 v4.4.x), 按照以上步骤再来一遍 43 | - **注意**:想要同步最新的 library 到 lts 分支, 你必须手动将 library 的新功能删除, 只保留修复部分, **需要特别小心不能出错**! 44 | - 将所有 API 更新变动同步到 [wiki.swoole.com](https://wiki.swoole.com) 45 | 46 | ## CI 相关 47 | 48 | 如果出现了只有 CI 中能复现的 bug, 可以通过 [travis/README.md](https://github.com/swoole/swoole-src/blob/master/travis/README.md) 中的指引在本地构建和 CI 相同的容器环境 49 | 50 | 更新过程中如发现问题, 修复后从头再来一遍 51 | -------------------------------------------------------------------------------- /v6.md: -------------------------------------------------------------------------------- 1 | # 6.0 2 | 3 | ## 目标 4 | 5 | 引入多线程运行模式,使 `Swoole` 实现多线程+协程的运行方式。 6 | 7 | ## 背景 8 | 在 `Swoole` 服务器编程开发中,协程的出现已经解决了大部分难题,但是我们发现跨进程读写数据依然很难,需要借助 进程间通信、Redis、Swoole\Table 或其他共享内存实现。 9 | 10 | `Redis`、`IPC` 进程间通信方式性能较差。而 `Swoole\Table` 的问题是需要固定分配内存,无法扩容,存在诸多限制。 11 | 12 | 除此之外,多进程的调试非常麻烦,例如我们要使用 gdb 就需要 `gdb -p` 逐个进程去追踪,而 Java 、Golang 这样的多线程模型,只有一个进程,调试更简单。实现一些底层的工具也会更容易。 13 | 14 | ## 实现方式 15 | 修改 `swoole-cli` 的 `CLI SAPI` 加入参数开启多线程,仅在 `ZTS` 模式下可用。 16 | 17 | ### 进程初始化时,按照传入的参数创建多个 `TSRM` 管理资源。 18 | ```c 19 | tsrm_startup(128, 1, 0, NULL); 20 | ``` 21 | ### 创建新线程时,隔离全局变量 22 | 23 | ```c 24 | std::thread newThread1([=]() { 25 | ts_resource(1); 26 | zend_first_try { 27 | mt_debug("thread-1"); 28 | do_cli(argc, argv); 29 | } 30 | zend_end_try(); 31 | }); 32 | ``` 33 | 34 | ### 运行结果 35 | 36 | ```php 37 | # index.php 38 | 84 | $map1 = Thread::map('global_map_1', Thread::TYPE_INT, Thread::TYPE_STRING); 85 | 86 | # 相当于 C++ 的 std::unorderedmap 87 | $map2 = Thread::map('global_map_2', Thread::TYPE_STRING, Thread::TYPE_FLOAT); 88 | 89 | # 相当于 C++ 的 std::vector 90 | $list = Thread::list('global_list_1', Thread::TYPE_INT); 91 | ``` 92 | 93 | - `Thread::once()` 可以让一个函数只运行一次 94 | - `Thread::map()` 创建全局 `HashTable` ,`Thread::list()` 创建全局列表,底层会自动加锁,是线程安全的 95 | - 支持 `int64/double/string` `3` 种格式 96 | 97 | 98 | 99 | ## 其他更新 100 | 101 | - 移除 `Coroutine\MySQL`、`Coroutine\Redis`、`Coroutine\PostgreSQL` ,已被 `pdo_mysql/mysqli`、`ext-redis`、`pdo_pgsql` 替代 102 | -------------------------------------------------------------------------------- /rpc.md: -------------------------------------------------------------------------------- 1 | 描述 2 | ==== 3 | 目前社区有很多 PHP 的 RPC 实现,但是在专业性上与其他编程语言存在差距。Swoole 底层内置一个 RPC 服务器/客户端,由 Swoole 团队支持维护,提高 PHP 在服务治理方面的通用性。 4 | 5 | * 状态:[草稿] 6 | * 版本:v4.6/v5.0 7 | 8 | > 服务治理方面推荐使用 `ServiceMesh` 的方案,使用`Istio`和`Envoy`实现 9 | > `Swoole RPC`仅提供基本的`RPC`通信协议层 10 | 11 | 12 | 设计 13 | ===== 14 | 特性列表 15 | ----- 16 | * 支持 FPM 下长连接,基于 `Swoole\Client`的`SWOOLE_KEEP`特性 17 | * 单连接并发 18 | * 请求/响应唯一序列号,可通过请求串号实现数据一致性校验、链路追踪 19 | * 同时支持协程、同步阻塞两种模式 20 | * 支持请求/响应压缩,降低带宽占用 21 | 22 | 与 GRPC、BRPC、Tars 的差异 23 | ----- 24 | Protobuf、Thrift、Tars 使用了 `IDL` 描述数据结构,配合代码生成工具,对静态语言更友好。而动态语言可以直接将对象、数组进行序列化传输,更简单、易用、灵活。 25 | 26 | 同时底层也会尽可能地兼容 Protobuf、Thrift、Tars、JSON、MsgPack 等编码格式。 27 | 28 | 在通信协议方面,底层会兼容各种常见的 GRPC、BRPC、Tars 的通信协议。 29 | 30 | 分层设计 31 | ---- 32 | 我们将整个 RPC 分为: 33 | 34 | - 通信层,如:Http2、Swoole RPC、B-RPC、GRPC、Tars 35 | - 编码层,如:PHP-Serialize、JSON、Protobuf、Thrift、Tars、MsgPack 36 | - 治理层,如:服务发现、故障转移、超时控制、智能重试、熔断、降级、限流、日志、监控、报警、链路追踪、性能分析、调试 37 | 38 | 支持范围 39 | ---- 40 | * 客户端:支持 FPM、Swoole 协程两种环境 41 | * 服务端:支持同步阻塞模式、协程模式 42 | 43 | 协程模式下提供更高级特性,FPM 同步客户端与同步阻塞服务端,仅支持基本的功能。 44 | 45 | 实现方法 46 | ---- 47 | 使用纯 PHP 代码实现,在 `swoole/library` 中实现,打包到 `Swoole` 内核。 48 | 49 | 伪代码 50 | ----- 51 | ### 客户端 52 | ```php 53 | call('/hello/world/test1', ['hello' => 'world1', 'name' => 'rango']); 58 | $response2 = $client->call('/hello/world/test2', ['hello' => 'world2', 'name' => 'rango']); 59 | $response3 = $client->call('/hello/world/test3', ['hello' => 'world3', 'name' => 'rango']); 60 | 61 | //并行调用 62 | $requeset1 = $client->send('/hello/world/test1', ['hello' => 'world1', 'name' => 'rango']); 63 | $requeset2 = $client->send('/hello/world/test2', ['hello' => 'world2', 'name' => 'rango']); 64 | $requeset3 = $client->send('/hello/world/test3', ['hello' => 'world3', 'name' => 'rango']); 65 | 66 | //通过 $request 和 $response 的 ID 来匹配 67 | $response3 = $client->recv(); 68 | $response1 = $client->recv(); 69 | $response2 = $client->recv(); 70 | 71 | 72 | ``` 73 | ### 服务端 74 | 75 | ```php 76 | on('Request', function ($request, $response) { 80 | var_dump($request->header); 81 | //根据 path 路由到不同的 controller 82 | var_dump($request->path); 83 | $response->end(['code' => 0, 'data' => 'hello world']); 84 | }); 85 | 86 | $server->start(); 87 | ``` 88 | 89 | 服务注册/发现 90 | ===== 91 | 92 | DNS [默认方式] 93 | ---- 94 | 默认使用 `DNS` 方式实现服务发现,但由于`DNS`仅支持发现,不支持注册,因此在`Server`端不做任何处理,直接监听端口。 95 | 96 | 在客户端,通过`DNS`获取`IP`地址进行`TCP`连接。可以搭建`HaProxy + LVS`作为网关,分发请求到不同的`Server`节点。 97 | 98 | ZooKeeper 99 | ---- 100 | 101 | ETCD 102 | ---- 103 | 104 | Consul 105 | ----- 106 | -------------------------------------------------------------------------------- /v5.md: -------------------------------------------------------------------------------- 1 | Swoole 5.0 版本规划 2 | ======================= 3 | 4 | > `master`分支不再作为 `4.9`,将调整为 `v5.0` 5 | 6 | 概览 7 | ---- 8 | - 支持 `PHP8.1` 9 | - 独立运行(`swoole-cli`) 10 | - 强类型,所有函数、类方法的参数、返回值均是有类型的 11 | - 强化底层服务治理能力 12 | - 强制要求 `PHP-8.0` 以上版本 13 | 14 | 15 | 新的运行模式 16 | ---- 17 | `5.0`将新增`swoole-cli`支持,`swoole`将像`node.js`这样作为独立程序提供给用户,而不是作为`PHP`的一个扩展。另外`swoole-cli`会尽可能地对`php-src`进行裁剪,移除一些不用的机制、模块、扩展、函数、类型、常量、代码,使得整个程序可以在几分钟之内编译完成。 18 | 19 | ```shell 20 | htf@htf-ThinkPad-T470p:~/workspace/php/awsl-psl$ ./swoole-cli -n -v 21 | Swoole 5.0.0 (cli) (built: Nov 26 2021 07:22:46) 22 | ``` 23 | 24 | #### 静态编译无依赖 25 | `swoole-cli`会全部使用静态编译连接方式,`libc`和`libstdc++`使用`musl`,并会包含`openssl`和`curl`库和扩展。用户可修改构建脚本添加其他更多三方扩展。 26 | 使得`swoole`程序不再依赖任何系统的`so`,可在任意`Linux`系统之间复制分发运行。 27 | 28 | ```shell 29 | htf@htf-ThinkPad-T470p:~/workspace/php/awsl-psl$ ldd swoole-cli 30 | 不是动态可执行文件 31 | htf@htf-ThinkPad-T470p:~/workspace/php/awsl-psl$ 32 | ``` 33 | 34 | #### 移除动态扩展加载机制 35 | 移除 `dl()` 函数和`php.ini`配置`extension={name}.so`的动态扩展加载机制,所有扩展必须为静态编译。 36 | `swoole-cli`允许自定义构建系统,将扩展添加到模块列表中 37 | 38 | #### 移除 `php -S` 内置服务器 39 | 在`swoole`环境下没有意义 40 | 41 | #### 移除内置扩展 42 | 移除使用率低、历史遗留、不支持协程的内置扩展,包括但不限于: 43 | - `com_dotnet` 44 | - `dba` 45 | - `ftp` 46 | - `ffi` 47 | - `imap` 48 | - `ldap` 49 | - `oci8` 50 | - `odbc` 51 | - `pdo_dblib` 52 | - `pdo_firebird` 53 | - `pdo_oci` 54 | - `pdo_odbc` 55 | - `pdo_pgsql` 56 | - `pgsql` 57 | - `pspell` 58 | - `shmop` 59 | - `snmp` 60 | - `sysvmsg` 61 | - `sysvsem` 62 | - `tidy` 63 | 64 | #### 移除函数 65 | 移除非 `cli` 模式、使用率低、历史遗留、不支持协程的内置函数,包括但不限于: 66 | - `checkdnsrr` 67 | - `dns_check_record` 68 | - `dns_get_mx` 69 | - `header` 70 | - `header_register_callback` 71 | - `header_remove` 72 | - `session_start` 73 | - `mail` 74 | 75 | #### 移除 ZTS 76 | 移除`ZTS`模式,在`cli`模式下`ZTS`是没有任何意义的。 77 | 78 | ```shell 79 | htf@htf-ThinkPad-T470p:~/workspace/php/awsl-psl$ ./swoole-cli -n -m 80 | [PHP Modules] 81 | Core 82 | curl 83 | date 84 | filter 85 | hash 86 | helper 87 | iconv 88 | inotify 89 | json 90 | openssl 91 | pcntl 92 | pcre 93 | posix 94 | redis 95 | Reflection 96 | session 97 | sockets 98 | SPL 99 | standard 100 | swoole 101 | 102 | [Zend Modules] 103 | ``` 104 | 105 | 106 | > `5.0`版本中依然支持作为`PHP`扩展的运行模式,但在下一个大版本`6.0`中将会移除扩展支持,只提供`swoole-cli`模式 107 | 108 | 超大文件上传 109 | ----- 110 | 从`5.0`开始`HTTP`服务器增加了对`超大文件上传`的支持,通过设置`upload_max_filesize`参数控制允许上传的文件最大尺寸。不同于`package_max_length`,超大文件上传功能是将`form-data`中的文件内容直接写入临时文件,这样的好处是不会占用太多内存,即可完成超大文件的上传。`package_max_length`可以设置为`2M`,`upload_max_filesize`设置为`2G`,每个连接只需要`2M`内存即可完成`2G`大文件的上传。 111 | 112 | ```php 113 | $server->set([ 114 | 'upload_max_filesize' => 2 * 1024 * 1024 * 1024, // 2G 115 | 'package_max_length' => 2 * 1024 * 1024, // 2M 116 | ]); 117 | ``` 118 | 119 | 120 | 新增 121 | ---- 122 | - 增加`Server`配置项:`max_concurrency`,可限制 `HTTP1/2` 服务的最大并发请求数量,超过之后返回 `503` 错误 123 | - 增加`Coroutine\Http\Client`配置项:`max_retries`,在发生连接失败、`HTTP 502/503` 时自动更换节点进行重试 124 | - 增加`name_resolver`全局配置项,强化域名解析能力,`5.0`之前的版本域名只能使用`DNS`解析,`5.0`之后可配置`name_resolver`将名字解析改为使用`Consul`或`Nacos`等服务发现插件 125 | - 增加`Coroutine::getExecuteTime()`,可获取协程实际执行时间(不包含处于`yield`状态的时间) 126 | - 增加`upload_max_filesize`配置,允许上传超大文件 127 | 128 | 强化 129 | ---- 130 | - 强类型,所有函数和类方法的参数和返回值增加了类型限定 131 | - 所有构造方法失败时全部修改为抛出异常 132 | 133 | 134 | 移除 135 | --- 136 | - 移除 `PSR-0` 风格类名,如 `swoole_http_server` 需要修改为 `Swoole\Http\Server` 137 | - 移除自动在 `shutdown function` 中添加 `Event::wait()`,必须显式调用 `Event::wait()` 进入事件等待,或者使用 `Co\run()`、`Server::start()`、`Process::start()`、`Process\Pool::start()` 等容器 138 | - 移除 `Server::tick/after/clearTimer/defer` 别名,直接使用 `Timer::tick()/Timer::after()/Timer::clear()/Event::defer()` 139 | -------------------------------------------------------------------------------- /ROLE.md: -------------------------------------------------------------------------------- 1 | 2 | English 3 | ==== 4 | 5 | Maintainer 6 | ---- 7 | * Continuously contribute code to any repo in swoole group for 1 year and its effective higher than 10 commit times, and can obtain the access to `admin/maintain/write` from the repo or its opposite team. 8 | * Within 1 year effective commit times is zero, remove maintainer permission. 9 | 10 | > Fix typo, fix grammar and wrong words, optimize error message, all above are not seen as effectual commit. 11 | > Add account to swoole group members as soon when get the access to maintainer 12 | 13 | Owner 14 | ---- 15 | * Obtained maintainer permission, meanwhile offer code for 3 years to master branches of swoole-src, library repo, and annual effective commit times are greater than 100, This account should be upgraded from maintainer to owner 16 | * Within 1 year effective commit times less than 10, cancel the owner permission and downgrade to maintainer. 17 | * When group members only have 1 owner, the owner automatically becomes guard, not close the access until new maintainer upgrade to new owner 18 | 19 | The swoole-src repository 20 | ----- 21 | * Non-owner access account ,not directly submit code to branches of master, firstly provide pull request.(here in after referred to as PR) 22 | * The `PR` couldn't merge to master until other maintainers review and agree, meanwhile, other owners obviously disagree. 23 | * Big changes in owner's access account, must submit PR; not merge to master until other maintainer review and accept. 24 | * Tiny changes in owner's access account, can directly submit to master, however other maintainers obviously make averse opinions, need to `revert commit` and restart a new process. 25 | * If PR is not reviewed by other maintainers beyond 3 days, then the operator self merge to master. 26 | 27 | Friendly cooperation 28 | ---- 29 | * Don't submit malicious content: virus, erotic, violent, politically sensitive, abusive code are forbidden apart from malicious overwriting of ohters' commit code. 30 | * Don't verbally attack, abuse or hurt other members and contributors. 31 | * Any account that violates the terms of friendly cooperation will remove all permissions and be removed from the swoole group members. 32 | 33 | 34 | 中文 35 | ==== 36 | 37 | 1 maintainer 38 | ----- 39 | * 1.1 持续 `1` 年向 `swoole group` 任意仓库贡献代码,并且有效 `commit` 次数高于 `10`,可以获得该仓库或对应 `team` 的 `admin/maintain/write` 操作权限 (以下简称 `maintainer` ) 40 | * 1.2 近 `1` 年内有效 `commit` 次数等于 `0` 时,移除 `maintainer` 权限 41 | 42 | > 修复拼写错误、优化错误信息、修复语法词法问题不计为有效 `commit` 43 | > 获得 `maintainer` 权限后会将此账户添加到 `swoole group members` 44 | 45 | 2 owner 46 | ----- 47 | 48 | * 2.1 拥有 `maintainer` 权限,并且持续 `3` 年向 `swoole-src`、`library` 两个核心仓库主分支贡献代码,每年有效 `commit` 次数高于 `100` 可以获得 `owner` 权限 49 | * 2.2 近 `1` 年内有效 `commit` 次数低于 `10`,移除 `owner` 权限,降级为 `maintainer` 权限 50 | * 2.2 当 `members` 中只有最后一个 `owner` 时,该 `owner` 自动成为看守者,不移除 `owner` 权限,直到有新的 `maintainer` 符合条件 `1` 成为新的 `owner` 51 | 52 | 3 swoole-src 仓库 53 | ----- 54 | * 3.1 非 `owner` 权限账户,不直接向 master 分支提交代码,需要先提交 `pull request` (以下简称`PR`) 55 | * 3.2 非 `owner` 权限账户 `PR` 经过其他 `maintainer` `review` 并同意后并且没有其他 `owner` 明确反对的情况下才可以 `merge` 到 `master` 56 | * 3.3 `owner` 权限账户重大变更必须提交 `PR`,经过其他 `maintainer` `review` 并且接受后才可以 merge 到 `master` 57 | * 3.4 `owner` 权限账户认为是轻微修改而直接提交到 `master`,其他 `maintainer` 明确提出反对意见,则需要要 `revert commit`,并按照第三条约定重新发起流程 58 | * 3.5 若 `PR` 在超过 `3` 天以上时间没有其他 `maintainer` 进行 `review`,发起者可以将此 `PR` 自行合并到 `master` 59 | 60 | 4 PECL 账户 61 | ---- 62 | * 4.1 `swoole-src` 和 `library` 仓库的 `maintainer` 可以将添加到 `PECL` 开发者列表中,`owner` 可作为 `lead` 角色,`maintainer` 作为 `developer` 角色 63 | * 4.2 近 `3` 年内不活跃的 `owner`(`lead` 角色)(参考 2.1 和 2.2)将 `active` 修改为 `no` 64 | * 4.3 近 `1` 年内不活跃的 `maintainer`(`developer` 角色)(参考 1.1 和 1.2)将 `active` 修改为 `no` 65 | * 4.4 违反第 `5` 条友好合作规定的账户,立即从 `PECL package.xml` 中删除 66 | 67 | 5 友好合作 68 | ----- 69 | * 5.1 不得恶意提交代码,如:提交存在病毒的代码,恶意覆盖其他人的 `commit` 代码,提交带有色情、暴力、政治敏感、辱骂攻击他人等恶意的内容,包括代码、文档、注释、评论、`Issue`等 70 | * 5.2 不对他人进行语言攻击,不得辱骂、伤害其他 `member`、`contributor` 71 | * 5.3 违反友好合作条款的账户应立即移除一切权限,并从 `swoole group members` 中移除 72 | --------------------------------------------------------------------------------