From b0d71a4c58c93f8398ea24e172c508fcdceed4fd Mon Sep 17 00:00:00 2001 From: qing <1776177662@qq.com> Date: Mon, 10 Aug 2026 05:39:00 +0000 Subject: [PATCH] =?UTF-8?q?core:=20=E7=A7=BB=E9=99=A4=20init.txt=20?= =?UTF-8?q?=E5=90=91=E5=90=8E=E5=85=BC=E5=AE=B9=EF=BC=8C=E4=BB=85=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20services.yaml?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - InitParser: 移除 parseTxt(),load() 不再回退 init.txt - pmc_mtd: parse_self_init_list 移除 TXT 分支,非 .yaml 文件报错退出 - main.cpp: --help 中 -i 参数描述移除 .txt - Makefile: install/uninstall 移除 init.txt 拷贝/删除 - services.yaml: 头注释移除 init.txt 相关措辞 - 删除 init.txt 文件 - README (core + 项目根): 全部 init.txt 引用替换为 services.yaml - core README: 补全 liblogc/yaml-cpp 依赖声明,修正文件结构 --- README.md | 28 +++++++---------- core/Makefile | 2 -- core/README.md | 49 +++++++++++++++-------------- core/include/registry/InitParser.hh | 16 +++------- core/init.txt | 15 --------- core/services.yaml | 5 ++- core/src/main.cpp | 2 +- core/src/main/pmc_mtd.cpp | 14 ++++----- core/src/registry/InitParser.cpp | 41 +----------------------- 9 files changed, 53 insertions(+), 119 deletions(-) delete mode 100644 core/init.txt diff --git a/README.md b/README.md index 8bd81f8..d8095b1 100755 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ ┌──────────────────────────────────────────────┐ │ core (PMC / Nidus) │ │ 进程托管服务 · 监听 :5200 (HTTP 管理接口) │ - │ 读取 init.txt 拉起并守护下列子进程 │ + │ 读取 services.yaml 拉起并守护下列子进程 │ └───────────────┬──────────────────────────────┘ │ 启动 / 守护 ┌──────────────────┬───────────┼───────────┬──────────────────┬──────────────┐ @@ -79,7 +79,7 @@ - 可执行文件 `nidus.out`,作为 systemd 服务(`Nidus.service`)常驻运行(崩溃守护由 systemd 负责,core 自身不含自动重启逻辑)。 - 支持两种工作模式:命令行子系统调用(`--send/--exec/--list/--kill`)与 HTTP 伺服器模式(`--serve `)。 - 通过命名管道(Pipe)与消息队列(Mq)实现进程间通信。 -- 读取 `init.txt` 自启动列表,按行拉起各业务服务(ai_review / db / dnfs / smtp / static / waf / ca / gateway / captcha / aibox)。 +- 读取 `services.yaml` 声明式配置,按声明顺序拉起各业务服务(db2 / ai_review / dnfs2 / smtp / fsys / waf / ca / gateway / captcha2 / aibox / redirect80)。 ### waf(WAF 网关) @@ -316,7 +316,7 @@ bash _set.sh # 构建 + 安装 bash _run.sh # 运行 ``` -部署路径约定为 `/opt/micro_servers/`,`core` 的 `init.txt` 即从该路径拉起其余服务。 +部署路径约定为 `/opt/micro_servers/`,`core` 的 `services.yaml` 即从该路径拉起其余服务。 > **注意**:`ai_review` / `aibox` / `redirect80` 已纳入 `_inst.sh`(分别依赖 chromadb ONNX 模型下载、`~/.cert/deepseek.key`、本地 `pymsg` 包)。`ai_review` 额外需配置 `.env` 文件(DeepSeek API 密钥等,参考 [ai_review/README.md](ai_review/README.md))。 @@ -324,20 +324,16 @@ bash _run.sh # 运行 ## 运行 -由 `core` 守护的子进程通过 `init.txt` 自启动(顺序很重要,redirect80 先于 waf、waf 先于 gateway): +由 `core` 守护的子进程通过 `services.yaml` 声明式配置自启动(顺序很重要,db2 先于 ai_review、waf 先于 redirect80)。配置详见 [core/services.yaml](core/services.yaml),摘录如下: -``` -bash /opt/micro_servers/db/_run.sh -bash /opt/micro_servers/confs/_run.sh -bash /opt/micro_servers/ai_review/_run.sh -bash /opt/micro_servers/dnfs/_run.sh -bash /opt/micro_servers/smtp/_run.sh -bash /opt/micro_servers/static/_run.sh -bash /opt/micro_servers/redirect80/_run.sh -bash /opt/micro_servers/waf/_run.sh -bash /opt/micro_servers/gateway/_run.sh -bash /opt/micro_servers/captcha/_run.sh -bash /opt/micro_servers/aibox/_run.sh +```yaml +services: + - name: db2 + cmd: bash /opt/micro_servers/db2/_run.sh + args: ["--instance", "db2", "--log-level", "info"] + depends_on: [] + sleep_before: 0 + # ... 其余 10 个服务(ai_review / dnfs2 / smtp / fsys / waf / ca / gateway / captcha2 / aibox / redirect80) ``` 启动 `core`(需 root 或 systemd): diff --git a/core/Makefile b/core/Makefile index 7c1722e..7d0fd27 100644 --- a/core/Makefile +++ b/core/Makefile @@ -68,7 +68,6 @@ install: $(APP_NAME).out @echo "正在配置 $(APP_NAME)" @mkdir -p $(CONF_DIR) @cp $(CONF_NAME) $(CONF_DIR)/$(CONF_NAME) - @cp init.txt $(CONF_DIR)/init.txt @cp $(SRV_NAME) $(SRV_DIR)/$(SRV_NAME) @systemctl daemon-reload @systemctl enable $(SRV_NAME) @@ -81,7 +80,6 @@ uninstall: @ @rm -f $(INSTL_DIRS)/$(APP_NAME) @rm -f $(CONF_DIRS)/$(CONF_NAME) - @rm -f $(CONF_DIRS)/init.txt @rm -f -d ${CONF_DIRS} @ @systemctl stop $(SRV_NAME) diff --git a/core/README.md b/core/README.md index 2452452..841b0d4 100644 --- a/core/README.md +++ b/core/README.md @@ -5,7 +5,7 @@ ## pmc 是一个什么项目? -PMC(Process Machine,进程机器)是一个可以创建、管理子进程以及模块的进程托管程序。你可以在它的托管下运行独立的业务模块,由 PMC 负责拉起与守护。它是整个 UniServe Framework 的**进程编排中枢**——读取 `init.txt` 自启动列表,顺序拉起并托管全部业务子进程(fsys / dnfs2 / db2 / ca / gateway / waf / captcha2 / smtp / ai_review / aibox / redirect80),并提供本地 HTTP 管理接口与内嵌配置服务。 +PMC(Process Machine,进程机器)是一个可以创建、管理子进程以及模块的进程托管程序。你可以在它的托管下运行独立的业务模块,由 PMC 负责拉起与守护。它是整个 UniServe Framework 的**进程编排中枢**——读取 `services.yaml` 声明式配置,顺序拉起并托管全部业务子进程(fsys / dnfs2 / db2 / ca / gateway / waf / captcha2 / smtp / ai_review / aibox / redirect80),并提供本地 HTTP 管理接口与内嵌配置服务。 崩溃守护由 systemd(`Nidus.service`)负责,PMC 自身**不含**自动重启子进程逻辑。 @@ -18,34 +18,36 @@ PMC(Process Machine,进程机器)是一个可以创建、管理子进程 ``` core/ ├── Makefile # 构建 / 安装(VERSION=0.1.0, APP_NAME=nidus) -├── init.txt # 自启动列表(逐行 bash 命令,# 开头为注释) +├── services.yaml # 声明式服务启动配置(name/cmd/args/env/depends_on/sleep_before) ├── Nidus.service # systemd 单元(User=root, ExecStart=_run.sh) -├── _run.sh # 启动:nidus.out -i init.txt --serve 5200 --confs 8010 +├── _run.sh # 启动:nidus.out -i . --serve 5200 --confs 8010 ├── _set.sh # 构建 + 创建 configs 符号链接 + make install ├── src/ │ ├── main.cpp # 入口:双模式 + 信号 + taskPool 生命周期 -│ └── main/ -│ ├── PPool.cpp # 子进程池 -│ ├── ProcessTask.cpp # boost.process 子进程封装 -│ ├── pmc_mtd.cpp # list / kill / exec / parse_self_init_list -│ ├── subsys_call.cpp # 跨机子系统调用(MQ 发令 + Pipe 回传) -│ ├── Tttask.cpp # 消息队列通信任务 -│ ├── HttpTask.cpp # 管理 HTTP 接口(:5200) -│ └── ConfsTask.cpp # 内嵌配置服务(:8010) +│ ├── main/ +│ │ ├── PPool.cpp # 子进程池 +│ │ ├── ProcessTask.cpp # boost.process 子进程封装 +│ │ ├── pmc_mtd.cpp # list / kill / exec / parse_self_init_list +│ │ ├── subsys_call.cpp # 跨机子系统调用(MQ 发令 + Pipe 回传) +│ │ ├── Tttask.cpp # 消息队列通信任务 +│ │ ├── HttpTask.cpp # 管理 HTTP 接口(:5200) +│ │ └── ConfsTask.cpp # 内嵌配置服务(:8010) +│ └── registry/ +│ └── InitParser.cpp # services.yaml 解析器 └── include/ ├── main/*.hh # PPool / ProcessTask / pmc_mtd / subsys_call / Tttask / HttpTask / ConfsTask + ├── registry/InitParser.hh # services.yaml 解析器 ├── tt/Pipe.h # IPC:命名管道(FIFO) ├── tt/Mq.h # IPC:消息队列 ├── logs/Logger.hpp # 单例日志 - ├── main/ConfsLogC.hpp # 内嵌 confs 异步日志客户端 └── cn/*.hpp # 中文化编程宏 ``` -> 注:早期 README 提到的 `users/`、`extra/` 子模块目录已不再使用,模块托管统一改为通过 `init.txt` 启动列表拉起各业务服务。 +> 注:早期 README 提到的 `users/`、`extra/` 子模块目录已不再使用,模块托管统一改为通过 `services.yaml` 配置拉起各业务服务。 ## 如何托管外部模块 -编辑启动列表 `init.txt`,每行写一条启动命令(以 `#` 开头的行视为注释)。PMC 启动时会逐行拉起(先 `clr()` 清理已退出进程,再 `crtp()` 创建)。**启动顺序很重要**(redirect80 → waf → ca → gateway …)。 +编辑 `services.yaml`,在 `services` 列表中声明每个服务的 `name`、`cmd`、`args`、`env`、`depends_on`、`sleep_before` 等字段。PMC 启动时按声明顺序逐个拉起(先 `clr()` 清理已退出进程,再 `crtp()` 创建)。**启动顺序很重要**(redirect80 → waf → ca → gateway …)。 ## 运行模式与命令行 @@ -59,7 +61,7 @@ PMC 支持两种工作模式: 此外: -- `-i ` / `--init`:指定自启动列表(常用 `init.txt`) +- `-i ` / `--init`:指定自启动配置(目录路径自动查找 `services.yaml`,或直接指定 `.yaml` 文件) - `--confs `:启用内嵌 confs 配置服务(默认 `127.0.0.1:8010`) - `-h` / `--help`:打印帮助与 API MAP(`/list` `/exec` `/kill` 路由) - `-v` / `--version`:打印版本号 @@ -67,7 +69,7 @@ PMC 支持两种工作模式: 实际启动命令(`_run.sh`): ```bash -./nidus.out -i init.txt --serve 5200 --confs 8010 +./nidus.out -i . --serve 5200 --confs 8010 ``` **生命周期**:注册 `SIGINT`/`SIGTERM` → `signalHandler` 唤醒条件变量 `cv` → 主线程 `cv.Wait()` 返回后遍历 `taskPool` 调用 `stop()` 优雅退出。 @@ -90,7 +92,7 @@ PMC 把所有常驻能力抽象为 `ITask`,用 `libth` 的 `Thread`(带 `sto - `list()` → 序列化所有子进程 `{index, pid, running, command}`。 - `kill(pid)` → 按 pid 遍历 `ppool` 匹配后 `kill(i)`。 - `exec(cmd)` → `ppool.crtp(cmd)`。 - - `parse_self_init_list(path)` → 逐行读 `init.txt`,去 `#` 注释与空行后 `clr()` + `crtp(row)`。 + - `parse_self_init_list(path)` → 经 `InitParser` 解析 `services.yaml`,按声明顺序 `clr()` + `crtp()` 拉起,支持 `sleep_before` 延时与 `env` 环境变量注入。 ## 架构:进程间通信层(`include/tt/`) @@ -117,7 +119,7 @@ PMC 把所有常驻能力抽象为 `ITask`,用 `libth` 的 `Thread`(带 `sto core 内置了统一配置服务(由 confs2 合并而来,pymsg RPC 协议,与 Python confs 完全兼容): ```bash -./nidus.out -i init.txt --serve 5200 --confs 8010 +./nidus.out -i . --serve 5200 --confs 8010 ``` - `--confs `:启用内嵌 confs 配置服务(get/list/reload/health 四个路由) @@ -139,7 +141,7 @@ core 内置了统一配置服务(由 confs2 合并而来,pymsg RPC 协议, - **`Logger`**(`logs/Logger.hpp`):单例,控制台输出,支持 DEBUG/INFO/WARNING/ERROR/CRITICAL 级别(注释标注为 DeepSeek 创作,TODO 改为文件存储)。 - **`include/cn/`**:中文化编程宏(`中文化.hpp` 等),提供 C++ 关键字中文别名。 -- **依赖库**(Makefile):`libth` `libhttp`/`libhttpclient` `libmsg` `libcurl` + boost(`program_options`/`json`/`thread`/`filesystem`)+ `ssl`/`crypto`/`pthread`。 +- **依赖库**(Makefile):`libth` `libhttp`/`libhttpclient` `libmsg` `liblogc` `libcurl` + boost(`program_options`/`json`/`thread`/`filesystem`)+ `yaml-cpp` + `ssl`/`crypto`/`pthread`。 ## PMC 的安装方式 @@ -154,6 +156,7 @@ sudo bash _set.sh sudo apt update sudo apt install git g++ make sudo apt install libboost-all-dev +sudo apt install libyaml-cpp-dev #sudo apt install libssl-dev #sudo apt install libcurl4-openssl-dev #sudo apt install libcurl4-gnutls-dev @@ -165,13 +168,13 @@ make # 等价于 make clear && make sudo make install # 装入 /usr/local/bin/nidus + systemd ``` -> `make install` 会把 `init.txt` 拷到 `/etc/Nidus/`、`Nidus.service` 拷到 `/etc/systemd/system`,并 `daemon-reload` + `enable` + `restart`。 +> `make install` 会把 `services.yaml` 拷到 `/etc/Nidus/`、`Nidus.service` 拷到 `/etc/systemd/system`,并 `daemon-reload` + `enable` + `restart`。 本仓库内的快捷方式: ```bash bash core/_set.sh # make clear && make + 建 configs 符号链接 + make install -bash core/_run.sh # 直接 ./nidus.out -i init.txt --serve 5200 --confs 8010 +bash core/_run.sh # 直接 ./nidus.out -i . --serve 5200 --confs 8010 ``` ## 加密通信机制(废弃) @@ -180,7 +183,7 @@ bash core/_run.sh # 直接 ./nidus.out -i init.txt --serve 5200 --confs 8010 ## 如何使用并发机器运行程序 -首先应该在模块中创建一个启动脚本,脚本中应该完成工作目录的切换、虚拟环境的激活,以及程序的启动。PMC 通过 `init.txt` 逐行执行这些启动脚本,从而把多个业务模块拉起并纳入托管。 +首先应该在模块中创建一个启动脚本,脚本中应该完成工作目录的切换、虚拟环境的激活,以及程序的启动。在 `services.yaml` 中声明该脚本后,PMC 会按声明顺序执行这些启动脚本,从而把多个业务模块拉起并纳入托管。 ## 已知待办与风险 @@ -193,6 +196,6 @@ bash core/_run.sh # 直接 ./nidus.out -i init.txt --serve 5200 --confs 8010 ## 上手要点 -- 调整自启动服务/顺序:编辑 `init.txt`(注释用 `#`)。 +- 调整自启动服务/顺序:编辑 `services.yaml`(在 `services` 列表中增删条目,调整声明顺序)。 - 管理接口调用:必须携带 admin token(经 gateway 签发),例如带 `Authorization: Bearer ` 或 `q4_token` Cookie 访问 `:5200`。 - 构建:`core/_set.sh`(会先创建 `configs → ../confs/configs` 符号链接,保证内嵌 confs 零迁移);`make clear && make` 后 `make install` 装入 systemd。 diff --git a/core/include/registry/InitParser.hh b/core/include/registry/InitParser.hh index f40939e..bd15da4 100644 --- a/core/include/registry/InitParser.hh +++ b/core/include/registry/InitParser.hh @@ -8,8 +8,7 @@ namespace qing::registry { /* 服务启动配置项 * - * 从 services.yaml 或 init.txt 解析出的单个服务声明。 - * YAML 模式下包含完整的元数据;TXT 模式下仅 cmd 有值。 + * 从 services.yaml 解析出的单个服务声明,包含完整的元数据。 */ struct ServiceConfig { std::string name; /* 服务唯一标识 */ @@ -25,25 +24,20 @@ struct ServiceConfig { /* 启动配置解析器 * - * 优先读 services.yaml(结构化声明),不存在则回退 init.txt(纯命令列表)。 - * 两种格式都输出 std::vector,调用方无需关心来源。 + * 仅读 services.yaml(结构化声明),输出 std::vector。 */ class InitParser { public: /* 入口:传入配置目录(如 /etc/Nidus) * - * 查找顺序: - * 1. /services.yaml → parseYaml() - * 2. /init.txt → parseTxt() - * 3. 都不存在 → 返回空 vector,调用方自行处理 + * 查找: + * /services.yaml → parseYaml() + * 不存在 → 返回空 vector,调用方自行处理 */ static std::vector load(const std::string& dir); /* 解析 services.yaml */ static std::vector parseYaml(const std::string& path); - - /* 解析 init.txt(向后兼容,每行一条命令,# 开头为注释) */ - static std::vector parseTxt(const std::string& path); }; } // namespace qing::registry diff --git a/core/init.txt b/core/init.txt deleted file mode 100644 index eff798f..0000000 --- a/core/init.txt +++ /dev/null @@ -1,15 +0,0 @@ -bash /opt/micro_servers/db2/_run.sh -bash /opt/micro_servers/ai_review/_run.sh -bash /opt/micro_servers/dnfs2/_run.sh -bash /opt/micro_servers/smtp/_run.sh -bash /opt/micro_servers/fsys/_run.sh -bash /opt/micro_servers/waf/_run.sh -bash /opt/micro_servers/ca/_run.sh -bash /opt/micro_servers/gateway/_run.sh -bash /opt/micro_servers/captcha2/_run.sh -bash /opt/micro_servers/aibox/_run.sh -bash /opt/micro_servers/redirect80/_run.sh - -# -#ssh-copy-id user@your-server -#ssh -D 1080 -N user@your-server diff --git a/core/services.yaml b/core/services.yaml index 2e4bc41..b3299b6 100644 --- a/core/services.yaml +++ b/core/services.yaml @@ -1,10 +1,9 @@ # core/services.yaml -# 声明式服务启动配置(替代 init.txt) -# 如果本文件存在则优先使用,否则回退 init.txt +# 声明式服务启动配置 # # 字段说明: # name 服务唯一标识(用于日志和未来注册中心) -# cmd 启动命令(与 init.txt 每行格式一致) +# cmd 启动命令 # args 传递给 _run.sh 的命令行参数列表(可选) # env 启动前设置的环境变量(可选) # depends_on 依赖的服务名列表(未来 DAG 拓扑排序用,当前仅记录) diff --git a/core/src/main.cpp b/core/src/main.cpp index 6500642..c930e64 100644 --- a/core/src/main.cpp +++ b/core/src/main.cpp @@ -149,7 +149,7 @@ int main(int argc, char** argv) { ("list", "list process all run") /* 列出运行中的进程 */ ("kill", po::value(), "kill a process") /* 杀死一个进程 */ /********* 子系统服务模式 ********/ - ("init,i", po::value(), "self-init config (dir or .yaml/.txt file)") /* 输入自启动配置 */ + ("init,i", po::value(), "self-init config (dir or .yaml file)") /* 输入自启动配置 */ ("serve", po::value(), "Run as http server") /* 启用http伺服器 */ ("confs", po::value(), "Run embedded confs rpc server"); /* 启用内嵌confs配置服务 */ diff --git a/core/src/main/pmc_mtd.cpp b/core/src/main/pmc_mtd.cpp index 68a264a..6834da1 100644 --- a/core/src/main/pmc_mtd.cpp +++ b/core/src/main/pmc_mtd.cpp @@ -93,14 +93,11 @@ catch(std::exception& exp) { /* 解析自启动列表、添加自启动项 * - * 兼容两种格式: - * - services.yaml(结构化声明,含 args/env/depends_on/sleep_before) - * - init.txt(纯命令列表,每行一条 bash 命令,# 开头为注释) + * 仅支持 services.yaml 格式(结构化声明,含 args/env/depends_on/sleep_before) * * path 可以是: - * - 目录路径 → 自动查找 services.yaml 或 init.txt + * - 目录路径 → 自动查找目录下的 services.yaml * - .yaml 文件 → 按 YAML 解析 - * - 其他文件 → 按 TXT 解析(向后兼容 init.txt) * * 如果在解析过程中出错,只是打印异常 */ void parse_self_init_list(std::string &path) @@ -110,14 +107,15 @@ try { std::vector services; if (fs::is_directory(path)) { - /* 目录模式:InitParser::load 自动查找 services.yaml → init.txt */ + /* 目录模式:InitParser::load 查找 services.yaml */ services = registry::InitParser::load(path); } else if (path.size() > 5 && path.substr(path.size() - 5) == ".yaml") { /* YAML 文件模式 */ services = registry::InitParser::parseYaml(path); } else { - /* TXT 文件模式(向后兼容 init.txt) */ - services = registry::InitParser::parseTxt(path); + /* 不再支持 init.txt 纯命令列表格式 */ + std::cerr << "parse_self_init_list: 不支持的配置格式,请使用 services.yaml" << std::endl; + return; } if (services.empty()) { diff --git a/core/src/registry/InitParser.cpp b/core/src/registry/InitParser.cpp index 4320fd0..f0970fe 100644 --- a/core/src/registry/InitParser.cpp +++ b/core/src/registry/InitParser.cpp @@ -25,21 +25,13 @@ std::vector InitParser::load(const std::string& dir) { namespace fs = std::filesystem; auto yaml_path = fs::path(dir) / "services.yaml"; - auto txt_path = fs::path(dir) / "init.txt"; - /* 优先 services.yaml */ if (fs::exists(yaml_path)) { std::cerr << "[InitParser] 使用 services.yaml: " << yaml_path << std::endl; return parseYaml(yaml_path.string()); } - /* 回退 init.txt */ - if (fs::exists(txt_path)) { - std::cerr << "[InitParser] 回退 init.txt: " << txt_path << std::endl; - return parseTxt(txt_path.string()); - } - - std::cerr << "[InitParser] 未找到 services.yaml 或 init.txt 于 " << dir << std::endl; + std::cerr << "[InitParser] 未找到 services.yaml 于 " << dir << std::endl; return {}; } @@ -95,37 +87,6 @@ std::vector InitParser::parseYaml(const std::string& path) { return result; } -std::vector InitParser::parseTxt(const std::string& path) { - std::vector result; - std::ifstream file(path); - if (!file.is_open()) { - std::cerr << "[InitParser] 无法打开 init.txt: " << path << std::endl; - return {}; - } - - std::string line; - while (std::getline(file, line)) { - /* 去除注释(# 之后的内容) */ - auto pos = line.find('#'); - if (pos != std::string::npos) - line = line.substr(0, pos); - - /* trim 空白 */ - auto first = line.find_first_not_of(" \t\r\n"); - if (first == std::string::npos) - continue; /* 空行 */ - auto last = line.find_last_not_of(" \t\r\n"); - line = line.substr(first, last - first + 1); - - ServiceConfig svc; - svc.cmd = line; - /* init.txt 模式下 name/args/env/depends_on/sleep_before 均为空/默认 */ - result.push_back(std::move(svc)); - } - - std::cerr << "[InitParser] init.txt 解析完成,共 " << result.size() << " 个服务" << std::endl; - return result; -} } // namespace qing::registry