core: 移除 init.txt 向后兼容,仅支持 services.yaml

- 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 依赖声明,修正文件结构
This commit is contained in:
qing committed 2026-08-10 05:39:00 +00:00
1 parent f041bf284b
commit b0d71a4c58
9 files changed
+53 -119

No files matched your search

+12 -16
View File
@@ -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 <port>`)。
- 通过命名管道(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):
-2
View File
@@ -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)
+26 -23
View File
@@ -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 <file>` / `--init`:指定自启动列表(常用 `init.txt`)
- `-i <dir/file>` / `--init`:指定自启动配置(目录路径自动查找 `services.yaml`,或直接指定 `.yaml` 文件)
- `--confs <port>`:启用内嵌 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 <port>`:启用内嵌 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 <token>` 或 `q4_token` Cookie 访问 `:5200`。
- 构建:`core/_set.sh`(会先创建 `configs → ../confs/configs` 符号链接,保证内嵌 confs 零迁移);`make clear && make` 后 `make install` 装入 systemd。
+5 -11
View File
@@ -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<ServiceConfig>,调用方无需关心来源。
* 仅读 services.yaml(结构化声明),输出 std::vector<ServiceConfig>。
*/
class InitParser {
public:
/* 入口:传入配置目录(如 /etc/Nidus)
*
* 查找顺序:
* 1. <dir>/services.yaml → parseYaml()
* 2. <dir>/init.txt → parseTxt()
* 3. 都不存在 → 返回空 vector,调用方自行处理
* 查找:
* <dir>/services.yaml → parseYaml()
* 不存在 → 返回空 vector,调用方自行处理
*/
static std::vector<ServiceConfig> load(const std::string& dir);
/* 解析 services.yaml */
static std::vector<ServiceConfig> parseYaml(const std::string& path);
/* 解析 init.txt(向后兼容,每行一条命令,# 开头为注释) */
static std::vector<ServiceConfig> parseTxt(const std::string& path);
};
} // namespace qing::registry
-15
View File
@@ -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
+2 -3
View File
@@ -1,10 +1,9 @@
# core/services.yaml
# 声明式服务启动配置(替代 init.txt)
# 如果本文件存在则优先使用,否则回退 init.txt
# 声明式服务启动配置
#
# 字段说明:
# name 服务唯一标识(用于日志和未来注册中心)
# cmd 启动命令(与 init.txt 每行格式一致)
# cmd 启动命令
# args 传递给 _run.sh 的命令行参数列表(可选)
# env 启动前设置的环境变量(可选)
# depends_on 依赖的服务名列表(未来 DAG 拓扑排序用,当前仅记录)
+1 -1
View File
@@ -149,7 +149,7 @@ int main(int argc, char** argv) {
("list", "list process all run") /* 列出运行中的进程 */
("kill", po::value<int>(), "kill a process") /* 杀死一个进程 */
/********* 子系统服务模式 ********/
("init,i", po::value<std::string>(), "self-init config (dir or .yaml/.txt file)") /* 输入自启动配置 */
("init,i", po::value<std::string>(), "self-init config (dir or .yaml file)") /* 输入自启动配置 */
("serve", po::value<int>(), "Run as http server") /* 启用http伺服器 */
("confs", po::value<int>(), "Run embedded confs rpc server"); /* 启用内嵌confs配置服务 */
+6 -8
View File
@@ -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<registry::ServiceConfig> 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()) {
+1 -40
View File
@@ -25,21 +25,13 @@ std::vector<ServiceConfig> 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<ServiceConfig> InitParser::parseYaml(const std::string& path) {
return result;
}
std::vector<ServiceConfig> InitParser::parseTxt(const std::string& path) {
std::vector<ServiceConfig> 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