diff --git a/README.md b/README.md index a8550bd..3092610 100755 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ └────────────┘ 日志链路: waf / ca / gateway / static / dnfs / ai_review / captcha / smtp / aibox / confs / redirect80 ──(log_client, pymsg)──► db:8005 (Logs 表) 认证链路(v0.9.0 起): waf:443 ──HTTP──► ca:8443 (认证+前置转发) ──HTTP──► gateway:8445 (纯转发, 仅 loopback) ──► 内部服务 - 配置链路: gateway / db2 / static / redirect80 / smtp / captcha ──(pymsg get)──► confs:8010(配置统一存放于 confs/configs/,mtime 变化自动重载;ca/dnfs2 例外,配置纯 CLI 传递) + 配置链路: gateway / db2 / static / smtp / captcha ──(pymsg get)──► confs:8010(配置统一存放于 confs/configs/,mtime 变化自动重载;ca/dnfs2/redirect80 例外,配置纯 CLI 传递) ``` > `db2` / `dnfs2` 分别是 `db` / `dnfs` 的 C++20 重实现(接口完全兼容,可平替),架构位置与 Python 版一致。`BotOps` 为 aibox 的终端前端(WebSocket 客户端),`lci` 为嵌入式帧缓冲图形界面,均不在上图中。 @@ -193,7 +193,7 @@ - 智能重定向:GET/HEAD → 301(搜索引擎友好永久重定向),POST/PUT/DELETE/PATCH → 308(保留方法与 body)。 - Host 保留:读取请求 `Host` 头构造重定向 URL(剥离端口),回退用配置的监听地址。 - 日志集成:通过 `log_client.py` 异步批量推送运行日志到 db 的 Logs 表(fail-safe)。 -- 配置分层:confs 强依赖(`confs/configs/redirect80.ini`,启动时 pymsg 阻塞等待拉取,confs 不可用时直接退出不做本地回退),环境变量(`REDIRECT80_*`)优先级最高。 +- 配置分层:CLI 参数(由 core/services.yaml 传入) > 环境变量(`REDIRECT80_*`) > 代码默认值,不依赖 confs。 - 80 端口为 Linux 特权端口(<1024),需 `CAP_NET_BIND_SERVICE` 或 root;`_run.sh` 自动尝试 `setcap`,或用 systemd `AmbientCapabilities`;详见 [redirect80/README.md](redirect80/README.md)。 ### confs(统一配置服务) @@ -210,7 +210,6 @@ | `gateway.ini` | gateway | confs 拉取(0.7.0 起配置完全迁入) | | `db.ini` | db / db2 | 强依赖(confs 未就绪自动重试) | | `static.ini` | static(fsys.py)/ fsys | 强依赖(拉取失败直接退出) | -| `redirect80.ini` | redirect80 | 强依赖(confs 不可用直接退出) | | `smtp.ini` | smtp / smtp3 | confs 拉取 | | `captcha.ini` | captcha / captcha2 | confs 拉取 | | `example.ini` | —(旧 gateway 示例模板) | 无消费方 | diff --git a/core/services.yaml b/core/services.yaml index 38cb423..b020482 100644 --- a/core/services.yaml +++ b/core/services.yaml @@ -139,6 +139,19 @@ services: # --- 端口重定向(最后启动) --- - name: redirect80 cmd: bash /opt/micro_servers/redirect80/_run.sh - args: ["--instance", "redirect80", "--log-level", "info"] + args: + - "--instance" + - "redirect80" + - "--log-level" + - "info" + # --- 配置全部经 CLI 传递(原 confs/configs/redirect80.ini 迁入) --- + - "--host" + - "0.0.0.0" + - "--port" + - "80" + - "--redirect-port" + - "443" + - "--redirect-code" + - "301" depends_on: [waf] sleep_before: 0 diff --git a/redirect80/README.md b/redirect80/README.md index 52dfbd6..8a15b18 100644 --- a/redirect80/README.md +++ b/redirect80/README.md @@ -8,18 +8,18 @@ - **智能重定向**:GET/HEAD → 301(搜索引擎友好永久重定向),POST/PUT/DELETE/PATCH → 308(保留方法和 body) - **Host 保留**:读取请求 `Host` 头构造重定向 URL(剥离端口),回退用配置的监听地址 - **日志集成**:通过 `log_client.py` 异步批量推送运行日志到 `db:8005` 的 Logs 表(fail-safe) -- **配置分层**:confs 强依赖 → 环境变量覆盖(`REDIRECT80_*`),confs 不可用时直接退出不做本地回退 +- **配置分层**:CLI 参数(由 core/services.yaml 传入) > 环境变量覆盖(`REDIRECT80_*`) > 代码默认值 ## 配置 -配置通过 confs 统一配置服务分发(`confs/configs/redirect80.ini`),启动时经 pymsg 阻塞等待拉取(retry_on_refused),confs 不可用时进程直接退出。环境变量优先级最高。 +配置通过三层加载(CLI > 环境变量 > 默认值),全部配置项由 core/services.yaml 经 CLI 参数传入,不依赖 confs。 -| 配置项 | 环境变量 | 默认值 | 说明 | -|--------|----------|--------|------| -| `host` | `REDIRECT80_HOST` | `0.0.0.0` | 监听地址 | -| `port` | `REDIRECT80_PORT` | `80` | 监听端口 | -| `redirect_port` | `REDIRECT80_REDIRECT_PORT` | `443` | 重定向目标 HTTPS 端口 | -| `redirect_code` | `REDIRECT80_REDIRECT_CODE` | `301` | 非 GET/HEAD 重定向状态码(308 vs 307) | +| 配置项 | CLI 参数 | 环境变量 | 默认值 | 说明 | +|--------|----------|----------|--------|------| +| `host` | `--host` | `REDIRECT80_HOST` | `0.0.0.0` | 监听地址 | +| `port` | `--port` | `REDIRECT80_PORT` | `80` | 监听端口 | +| `redirect_port` | `--redirect-port` | `REDIRECT80_REDIRECT_PORT` | `443` | 重定向目标 HTTPS 端口 | +| `redirect_code` | `--redirect-code` | `REDIRECT80_REDIRECT_CODE` | `301` | GET/HEAD 重定向状态码 | ## 安装 & 运行 @@ -45,21 +45,28 @@ AmbientCapabilities=CAP_NET_BIND_SERVICE ExecStart=/opt/micro_servers/redirect80/_run.sh ``` -## 在 core 的 init.txt 中 +## 在 core 的 services.yaml 中 -``` -bash /opt/micro_servers/redirect80/_run.sh -``` +redirect80 作为最后一个服务启动,配置全部经 CLI 传入: -建议放在 waf 之前: - -``` -bash /opt/micro_servers/db/_run.sh -bash /opt/micro_servers/confs/_run.sh -bash /opt/micro_servers/redirect80/_run.sh # ← 80→443 重定向 -bash /opt/micro_servers/waf/_run.sh -bash /opt/micro_servers/gateway/_run.sh -... +```yaml +- name: redirect80 + cmd: bash /opt/micro_servers/redirect80/_run.sh + args: + - "--instance" + - "redirect80" + - "--log-level" + - "info" + - "--host" + - "0.0.0.0" + - "--port" + - "80" + - "--redirect-port" + - "443" + - "--redirect-code" + - "301" + depends_on: [waf] + sleep_before: 0 ``` ## 端口一览 diff --git a/redirect80/redirect80.py b/redirect80/redirect80.py index 0d2465e..2c77132 100644 --- a/redirect80/redirect80.py +++ b/redirect80/redirect80.py @@ -8,14 +8,12 @@ redirect80 — HTTP 80 端口重定向服务。 日志通过 log_client 异步推送到 db 的 Logs 表(fail-safe)。 配置(三层加载): - 1. confs 强依赖拉取 redirect80.ini(retry_on_refused 阻塞等待) - 2. 环境变量覆盖(Docker/k8s 兼容) - 3. 命令行参数(最高优先级) -配置不可用时直接退出,不做本地回退。 + 1. 代码默认值 + 2. 环境变量覆盖(REDIRECT80_* 前缀,Docker/k8s 兼容) + 3. 命令行参数(最高优先级,由 core/services.yaml 传入) """ import argparse -import configparser import os import sys as _sys from http.server import HTTPServer, BaseHTTPRequestHandler @@ -26,14 +24,11 @@ _here = os.path.dirname(os.path.abspath(__file__)) _sys.path.insert(0, os.path.join(_here, "..")) from log_client import logs, set_log_level # noqa: E402 -_sys.path.insert(0, os.path.join(_here, "..", "pymsg")) -from pymsg import RpcClient # noqa: E402 - # ── 配置加载 ───────────────────────────────────────────────────────── def load_config(argv): - """三层加载: confs → ENV → CLI(最高优先级)。""" + """三层加载: 默认值 → ENV → CLI(最高优先级)。""" # argparse 先行:--help 在任何网络调用前处理 parser = argparse.ArgumentParser( @@ -41,7 +36,7 @@ def load_config(argv): description="HTTP 80 端口重定向服务", add_help=False, formatter_class=argparse.RawDescriptionHelpFormatter, - epilog="配置优先级: CLI > 环境变量 > confs > 默认值", + epilog="配置优先级: CLI > 环境变量 > 默认值", ) parser.add_argument("--host", default=None, help="绑定地址,默认 0.0.0.0") @@ -69,35 +64,7 @@ def load_config(argv): "instance": "redirect80", } - # 1. confs 强依赖拉取配置(阻塞等待 confs 就绪,失败则退出) - confs_host = os.environ.get("CONFS_HOST", "127.0.0.1") - confs_port = int(os.environ.get("CONFS_PORT", "8010")) - try: - client = RpcClient( - confs_host, confs_port, "redirect80", - retry_on_refused=True, timeout=5, - ) - data = client.call("get", {"name": "redirect80.ini"}) - ini_text = data.get("content", "") - ini = configparser.ConfigParser(interpolation=None) - ini.read_string(ini_text) - - _merge = { - ("server", "host"): "host", - ("server", "port"): "port", - ("server", "redirect_port"): "redirect_port", - ("server", "redirect_code"): "redirect_code", - } - for (sec, key), var in _merge.items(): - if ini.has_option(sec, key): - val = ini.get(sec, key) - config[var] = type(config[var])(val) - logs.info("redirect80", "配置已从 confs 加载") - except Exception as e: - print(f"[redirect80] confs 获取失败: {e}", file=_sys.stderr) - _sys.exit(1) - - # 2. 环境变量覆盖 + # 1. 环境变量覆盖 _env_map = { "REDIRECT80_HOST": "host", "REDIRECT80_PORT": ("port", int), @@ -112,7 +79,7 @@ def load_config(argv): else: config[mapping] = val - # 3. CLI 参数(最高优先级) + # 2. CLI 参数(最高优先级) if args.host is not None: config["host"] = args.host if args.port is not None: