diff --git a/.gitignore b/.gitignore index 3314b6c6..b505552a 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ composer.lock /resources/zhamao.service .phpunit.result.cache .daemon_pid -/runtime/ \ No newline at end of file +/runtime/ +/tmp/ \ No newline at end of file diff --git a/README.md b/README.md index c90d57f8..b5a98acc 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ public function index() { ## 下载源码 框架源码可直接克隆本仓库进行编辑,如果你在国内,访问 GitHub 和 clone 仓库比较慢,可以将 `github.com` 替换为 `fgit.zhamao.me` 进行加速。 -例如:`git clone https://fgit.zhamao.me/zhamao-robot/zhamao-framework.git`。 +例如:`git clone https://fgit.zhamao.me/zhamao-robot/zhamao-framework.git --depth 1`。 ## 贡献和捐赠 如果你在使用过程中发现任何问题,可以提交 Issue 或自行 Fork 后修改并提交 Pull Request。 diff --git a/docs/advanced/custom-start.md b/docs/advanced/custom-start.md index 5bcff75b..68bee88d 100644 --- a/docs/advanced/custom-start.md +++ b/docs/advanced/custom-start.md @@ -86,15 +86,19 @@ bin/start server # 通过源码模式启动框架 - `--log-{mode}`:设置 log 等级。支持 `--log-debug`,`--log-verbose`,`--log-info`,`--log-warning`,`--log-error`。 - `--log-theme`:设置终端信息的主题。这个选项适用于多种终端信息显示的兼容,例如白色终端和不支持颜色的终端。详见 [Console - 主题设置](/component/console/#_2)。 - `--disable-coroutine`:关闭一键协程化。 +- `--remote-terminal`:开启 nc 远程终端,配置文件使用全局中的 `remote_terminal` 项。也可以在全局配置中常开启(status 设置为 true)。 - `--daemon`:以守护进程方式运行框架,此参数将直接在输出 motd 后将进程挂到 init 下运行,后台常驻。 -- `--watch`:监控 `src/` 目录下的文件变化,有变化则自动重新载入代码。开启监控需要安装 PHP 扩展:inotify。使用 pecl 就可以安装:`pecl install inotify`。 +- `--watch`:监控 `src/` 目录下的文件变化,有变化则自动重新载入代码。开启监控需要安装 PHP 扩展:inotify。使用 pecl 就可以安装:`pecl install inotify`。(注:不支持 WSL 和 macOS) - `--env`:设置运行环境,设置运行环境后将优先加载指定环境的配置文件,支持 `--env=production`,`--env=staging`,`--env=development`,见 [基本配置](/guide/basic-config/#_2)。 +- `--worker-num`:指定运行的工作进程数量(并不是越多越好,框架默认为 CPU 核心数),例如 `--worker-num=8`。 +- `--task-worker-num`:启用 TaskWorker 进程并指定数量。 +- `--show-php-ver`:在启动时显示 Swoole 和 PHP 的版本。 ## 守护进程操作命令 守护进程在 2.2.0 版本开始,可以使用命令行快速操作,如重启、停止、查看状态等。 -注意,这里的守护进程操作命令是指 **使用 `--daemon` 方式启动的框架**,如使用 Docker、screen、tmux 等方式挂后台跑则此命令不可用! +注意,这里的守护进程操作命令是指 **使用 `--daemon` 方式启动的框架**,如使用 Docker、screen、tmux、systemd 等方式挂后台跑则此命令不可用! ```bash vendor/bin/start daemon:status # 查看守护进程的状态 @@ -115,4 +119,16 @@ vendor/bin/start simple-http-server your-web-dir/ --host=0.0.0.0 --port=8080 ``` - `your-web-dir` 是必填的参数。 -- `--host` 和 `--port` 是可选参数,如果不填,则默认使用 `global.php` 配置文件中的配置。 \ No newline at end of file +- `--host` 和 `--port` 是可选参数,如果不填,则默认使用 `global.php` 配置文件中的配置。 + +### 检查配置是否更新 + +默认情况下(非源码模式),你可以使用命令 `vendor/bin/start check:config` 来检查你的配置文件是否需要更新部分段落。 + +### systemd 配置文件生成器 + +框架支持生成 systemd 配置文件 `zhamao.service`,生成后将文件放入 `/etc/systemd/system` 后输入 `systemctl enable zhamao.service` 即可。 + +命令:`vendor/bin/start systemd:generate` + +注意,systemd 启动的守护进程模式和使用参数 `--daemon` 不一样,请勿同时混用,直接使用上述命令生成的配置文件即可正常使用! \ No newline at end of file diff --git a/docs/advanced/framework-structure.md b/docs/advanced/framework-structure.md index 8511afc1..e3259b69 100644 --- a/docs/advanced/framework-structure.md +++ b/docs/advanced/framework-structure.md @@ -2,5 +2,5 @@ ## 框架运行总结构图 -![](../assets/img/framework-structure.png) +![](https://static.zhamao.me/images/docs/a23d8a952cf9c88d395888d220605a4f.png) diff --git a/docs/advanced/multi-process.md b/docs/advanced/multi-process.md index 7443b516..3238c028 100644 --- a/docs/advanced/multi-process.md +++ b/docs/advanced/multi-process.md @@ -16,13 +16,13 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采 **但是**,CPU 密集型的应用怎么办呢?假设我的 Web 应用有大量的排序、md5 运算怎么办呢?这样的阻塞,假设是一个超级大的 for 循环或者是要执行很长时间的 while 循环,CPU 一直在被占用。多进程就是针对 CPU 密集型的应用说 yes 的一个方案。 -![Untitled Diagram (1)](../assets/img/single-process.png) +![diagram](https://static.zhamao.me/images/docs/06c17ab473f17ab10523a938cdbd8760.png) 我们假设现在有 3 个请求同时访问,也就是说上面的流程需要执行 3 遍。而如果我们只有一个进程的话,最后一个请求需要等待的时间为 `2*3+5*3=21` 秒,非常耗时。 而如果有两个进程处理 3 个请求,则最后一个完成的请求就缩短了,`2+5+2+5=14` 秒。 -![Untitled Diagram (2)](../assets/img/Untitled Diagram (2).png) +![diagram](https://static.zhamao.me/images/docs/dbb4e32e1c77f96162d10e41f25befa4.png) 所以如果要充分利用你的服务器或者个人电脑的多核 CPU 资源,就要设置多个进程来处理。一个进程只能在一个 CPU 上运行,而设置了多进程后,就可以让多核 CPU 充分运行多个进程,所以我们给框架设置多进程的推荐数值为等同于 CPU 的核心数。 @@ -32,7 +32,7 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采 ## 框架进程模型 -![Untitled Diagram (3)](../assets/img/Untitled Diagram (3).png) +![diagram](https://static.zhamao.me/images/docs/46a34feb0195d6ea12da7b80750c9e71.png) 上图中,横向的时间片可以理解为并行执行,这些操作在多个 CPU 内可能同时在执行。 @@ -40,7 +40,7 @@ PHP 也是如此,框架的多进程又是怎么一回事呢?为什么要采 众所周知,进程是程序在操作系统中的一个边界,和自己有关的一切变量、内容和代码都在自己的进程内,不同进程之间如果不使用管道等方式,是不可以互相访问的。而加上开始描述的,创建子进程是一个复制自身的过程,所以也就会有如下图的情况: -![Untitled Diagram (4)](../assets/img/Untitled Diagram (4).png) +![diagram](https://static.zhamao.me/images/docs/8b43e2179a63c8d91a508d7cefcd3226.png) 我们以静态类为例,设置一个进程中的全局变量。这里就会出现,同一个静态变量在多个进程中完全不同的值的结果。此后,我们将会在 Worker 进程中执行用户的代码,如果设置 Worker 数量仅为 1 的话,那么就简单许多了,你还是可以使用全局变量或静态类来存储你想要的内容而不用担心这种多个进程变量隔离的情况(因为用户的 Web 请求处理的代码只会在一个 Worker 进程中执行)。如果像上图一样设置了多个 Worker,则用户过来的比如 HTTP 请求就有可能出现在不同的 Worker 进程中,给全局变量设值就一定会造成不同步的问题。这时我们就不可以使用全局变量做数据同步(注意,我说的是数据同步)。 diff --git a/docs/advanced/task-worker.md b/docs/advanced/task-worker.md index 18495898..fda8ffcb 100644 --- a/docs/advanced/task-worker.md +++ b/docs/advanced/task-worker.md @@ -1,3 +1,4 @@ # 使用 TaskWorker 进程处理密集运算 -> 新开个坑,有时间补上。(__填坑标记__) \ No newline at end of file +> 新开个坑,有时间补上。(__填坑标记__) + diff --git a/docs/assets/img/CB86FE26-7EC7-4480-83FF-DE29285D1C7B.png b/docs/assets/img/CB86FE26-7EC7-4480-83FF-DE29285D1C7B.png deleted file mode 100644 index b61c99fd..00000000 Binary files a/docs/assets/img/CB86FE26-7EC7-4480-83FF-DE29285D1C7B.png and /dev/null differ diff --git a/docs/assets/img/Untitled Diagram (2).png b/docs/assets/img/Untitled Diagram (2).png deleted file mode 100644 index 404c65ba..00000000 Binary files a/docs/assets/img/Untitled Diagram (2).png and /dev/null differ diff --git a/docs/assets/img/Untitled Diagram (3).png b/docs/assets/img/Untitled Diagram (3).png deleted file mode 100644 index 58b7841a..00000000 Binary files a/docs/assets/img/Untitled Diagram (3).png and /dev/null differ diff --git a/docs/assets/img/Untitled Diagram (4).png b/docs/assets/img/Untitled Diagram (4).png deleted file mode 100644 index 0706b558..00000000 Binary files a/docs/assets/img/Untitled Diagram (4).png and /dev/null differ diff --git a/docs/assets/img/Untitled Diagram.png b/docs/assets/img/Untitled Diagram.png deleted file mode 100644 index 841f2dd4..00000000 Binary files a/docs/assets/img/Untitled Diagram.png and /dev/null differ diff --git a/docs/assets/img/diagram3.dbb4e32e.png b/docs/assets/img/diagram3.dbb4e32e.png deleted file mode 100644 index 7baa6733..00000000 Binary files a/docs/assets/img/diagram3.dbb4e32e.png and /dev/null differ diff --git a/docs/assets/img/diagram4.16ce39ca.png b/docs/assets/img/diagram4.16ce39ca.png deleted file mode 100644 index ea88b527..00000000 Binary files a/docs/assets/img/diagram4.16ce39ca.png and /dev/null differ diff --git a/docs/assets/img/framework-structure.png b/docs/assets/img/framework-structure.png deleted file mode 100644 index 6a59290e..00000000 Binary files a/docs/assets/img/framework-structure.png and /dev/null differ diff --git a/docs/assets/img/single-process.png b/docs/assets/img/single-process.png deleted file mode 100644 index 679ad67e..00000000 Binary files a/docs/assets/img/single-process.png and /dev/null differ diff --git a/docs/component/global-functions.md b/docs/component/global-functions.md index 27379d7c..d90fe552 100644 --- a/docs/component/global-functions.md +++ b/docs/component/global-functions.md @@ -267,7 +267,7 @@ $pass->obj = true; zm_dump($pass); ``` -![](../assets/img/CB86FE26-7EC7-4480-83FF-DE29285D1C7B.png) +![](https://static.zhamao.me/images/docs/ba026ca11332b1a4ad68a549165230e6.png) ## zm_config() diff --git a/docs/component/remote-terminal.md b/docs/component/remote-terminal.md new file mode 100644 index 00000000..be464c74 --- /dev/null +++ b/docs/component/remote-terminal.md @@ -0,0 +1,37 @@ +# 远程终端 +框架在 2.3 版本时删除了本地终端(就是框架启动后可以在终端输入一些参数),因为框架的多进程模式会导致终端输入错乱,所以暂时取消掉了。 + +而远程终端应运而生,为的是弥补这一功能。与之前不同的是,远程终端使用 nc 连接,无需任何其他组件和客户端,而且功能更丰富,支持自定义命令。 + +## 启用 +有两种开启方式: + +- 永久开启:全局配置文件中找到 `remote_terminal` 的 `status`,改为 true,启动框架即可。 +- 临时开启:启动框架时加上参数 `--remote-terminal`。例如:`vendor/bin/start server --remote-terminal`。 + +## 配置 +在一般情况下,框架为了安全,直接按照默认配置,会监听 `127.0.0.1:20002` 端口,不可以远程访问,只能使用本机的 nc 连接,效果如下: + +本地主机: +![img.png](https://static.zhamao.me/images/docs/3432551c08b34ca10aaf19f3f82aedeb.png) + +从别的主机: +![img.png](https://static.zhamao.me/images/docs/6f35f2745d66c7e186da75b6f09248c2.png) + +如果将 `host` 改为 `0.0.0.0` 或对应监听地址,即可指向性访问。 + +但是,如果你又想远程连接,又想保证安全,那么可以设置一个 token 参数,来保证连接时需要输入 token 才能使用远程终端。 +假设我们的 token 是 `iAMTokEn`: +![img.png](https://static.zhamao.me/images/docs/e502af4c0fd9359615548303cacb70dd.png +) + +## 使用 +默认情况下,使用 `nc` 命令即可。 +```bash +nc -vvv +# nc 127.0.0.1 20002 -vvv +``` + +输入 help 即可查看内置的常用指令: +![img.png](https://static.zhamao.me/images/docs/7b74aa2b487c86482097ec7692c66e08.png +) \ No newline at end of file diff --git a/docs/event/event-dispatcher.md b/docs/event/event-dispatcher.md index 9ddad1e5..08c547e7 100644 --- a/docs/event/event-dispatcher.md +++ b/docs/event/event-dispatcher.md @@ -102,15 +102,15 @@ class Test { 在炸毛框架内部,一个完整的事件流程和中间件的关系如下图: -![Untitled Diagram](../assets/img/diagram3.dbb4e32e.png) +![Untitled Diagram](https://static.zhamao.me/images/docs/dbb4e32e1c77f96162d10e41f25befa4.png) 对于同一事件的优先级和响应顺序,优先级的关系如下图: -![Untitled Diagram](../assets/img/Untitled Diagram.png) +![diagram](https://static.zhamao.me/images/docs/fa52005b7ca891053617a77541c7e785.png) 对于事件内单个事件被调用的单个函数下如果存在多个中间件,中间件模型和事件的关系如下图: -![Untitled Diagram-2](../assets/img/diagram4.16ce39ca.png) +![Untitled Diagram-2](https://static.zhamao.me/images/docs/16ce39caad472d03d7786e6ffb0c55bf.png) ## 实战例子 diff --git a/docs/guide/basic-config.md b/docs/guide/basic-config.md index 61a32ca6..4bbf427a 100644 --- a/docs/guide/basic-config.md +++ b/docs/guide/basic-config.md @@ -18,6 +18,7 @@ | `zm_data` | 框架的配置文件、日志文件等文件目录 | `./` 下的 `zm_data/` | | `debug_mode` | 框架是否启动 debug 模式 | false | | `crash_dir` | 存放崩溃和运行日志的目录 | `zm_data` 下的 `crash/` | +| `config_dir` | 存放 saveToJson() 方法保存的数据的目录 | `zm_data` 下的 `config/` | | `swoole` | 对应 Swoole server 中 set 的参数,参考Swoole文档 | 见子表 `swoole` | | `light_cache` | 轻量内置 key-value 缓存 | 见字表 `light_cache` | | `worker_cache` | 跨进程变量级缓存 | 见子表 `worker_cache` | @@ -28,11 +29,11 @@ | `http_default_code_page` | HTTP服务器在指定状态码下回复的默认页面 | 见配置文件 | | `init_atomics` | 框架启动时初始化的原子计数器列表 | 见配置文件 | | `info_level` | 终端日志显示等级(0-4) | 2 | -| `context_class` | 上下文所定义的类,待上下文完善后见对应文档 | `\ZM\Context\Context::class` | +| `context_class` | 上下文所定义的类,见对应上下文说明文档 | `\ZM\Context\Context::class` | | `static_file_server` | 静态文件服务器配置项 | 见子表 `static_file_server` | -| `server_event_handler_class` | 注册 Swoole Server 事件注解的类列表 | 见配置文件 | -| `command_register_class` | 注册自定义命令行选项指令的类 | 见配置文件 | -| `modules` | 服务器启用的外部第三方和内部插件 | `['onebot' => true]` | +| `server_event_handler_class` | 注册 Swoole Server 事件注解的类列表,在 Swoole 服务器启动前就被加载 | 空 | +| `onebot` | OneBot 协议相关配置 | 见子表 `onebot` | +| `remote_terminal` | 远程终端相关配置 | 见子表 `remote_terminal` | ### 子表 **swoole** @@ -91,6 +92,23 @@ | `document_root` | 静态文件的根目录 | `{WORKING_DIR}/resources/html` | | `document_index` | 默认索引的文件名列表 | `["index.html"]` | +### 子表 onebot + +| 配置名称 | 说明 | 默认值 | +| ----------------- | ------------------------------------------------------------ | ------ | +| `status` | 是否开启 OneBot 标准机器人解析功能 | true | +| `single_bot_mode` | 是否开启单机器人模式 | false | +| `message_level` | 机器人的 WebSocket 事件在 Swoole 原生事件 `@OnMessageEvent` 中的等级(越高说明越被优先处理) | 99999 | + +### 子表 remote_terminal + +| 配置名称 | 说明 | 默认值 | +| -------- | ------------------------------------------------------------ | ----------- | +| `status` | 是否开启远程终端功能,见 [组件 - 远程终端](/component/remote-terminal) | false | +| `host` | 远程终端监听地址,为安全起见,默认值只允许本地回环地址(127.0.0.1) | `127.0.0.1` | +| `port` | 远程终端监听的 TCP 端口 | 20002 | +| `token` | 远程终端连接的令牌(如果为空("")则不验证) | "" | + ## 多环境下的配置文件 炸毛框架的配置文件模块支持不同环境下的配置文件,主要结构为 `global.{环境}.php`。在一般情况下,炸毛框架默认从教程引导方式根据指令 `vendor/bin/start server` 启动的框架是不带环境控制的。这章将讲述如何根据不同的环境(development / staging / production)来编写配置文件。