From 44ffee79c7f5abe9204b5b472c449d29d845b9e7 Mon Sep 17 00:00:00 2001 From: chakcy <947105045@qq.com> Date: Wed, 5 Aug 2026 18:18:48 +0800 Subject: [PATCH] =?UTF-8?q?modify:=20=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 358 +++++++++++++++++---------------- config.toml | 1 - src/chongming/scripts/build.py | 8 +- 3 files changed, 186 insertions(+), 181 deletions(-) diff --git a/README.md b/README.md index 5441739..d5b35e6 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,27 @@ 基于 **FastAPI + Zenoh + MQTT + Vue 3** 的**配置驱动微服务网关平台**。 -核心理念:通过 TOML 配置文件定义 RPC 端点,自动生成 Pydantic 模型,同时暴露 **HTTP** 和 **MQTT** 双通道。 -底层通过 Zenoh 分布式消息协议进行 RPC 通信,Worker 插件可独立开发、热加载、水平扩展。 +通过 TOML 配置文件定义 RPC 端点,自动生成 Pydantic 模型与 FastAPI 路由,同时暴露 **HTTP** 和 **MQTT** 双通道。底层基于 Zenoh 分布式消息协议实现 RPC 通信,Worker 插件可独立开发、热加载、水平扩展。 --- ## 核心特性 -- **FastAPI + Uvicorn**:高性能异步 Web 框架,自动生成 OpenAPI 文档 -- **Zenoh 服务发现**:基于 Zenoh liveliness 的 Worker 注册与 RPC 调用,负载均衡 + 超时重试 -- **MQTT 集成**:内嵌 amqtt Broker,MQTT 消息自动桥接到 Worker 插件,支持请求/响应与单向上报 -- **动态路由生成**:扫描 `config/workers` TOML 配置自动生成 HTTP 路由,`[MQTT]` 节单独处理 -- **Worker 框架**:`@rpc_method` 装饰器定义 RPC 方法,自动参数解析与 Pydantic 模型绑定 -- **自动化模型生成**:`gen_models` 脚本根据 TOML 配置生成请求/响应 Pydantic 模型(含 MQTT) -- **JWT 鉴权**:Rust 实现,路由级别 `auth_required` 控制 -- **Argon2id 密码哈希**:Rust 实现的高性能密码安全方案 -- **文件存储**:本地文件系统上传/下载 -- **构建打包**:支持 PyInstaller / Nuitka 一键打包为独立可执行文件 -- **Vue 3 前端**:Element Plus UI、Pinia 状态管理、自动生成类型安全的 API 客户端 +| 特性 | 说明 | +| --------------------- | -------------------------------------------------------------- | +| **FastAPI + Uvicorn** | 高性能异步 Web 框架,自动生成 OpenAPI 文档 | +| **Zenoh 服务发现** | 基于 liveliness 的 Worker 注册与 RPC 调用,负载均衡 + 超时重试 | +| **MQTT 集成** | 内嵌 amqtt Broker,MQTT ↔ Worker 双向桥接 | +| **动态路由生成** | 扫描 `config/workers/*.toml` 自动注册 HTTP 路由 | +| **Worker 框架** | `@rpc_method` 装饰器 + 自动参数解析 + Pydantic 模型绑定 | +| **自动化模型生成** | `gen_models` 根据 TOML 配置生成请求/响应模型 | +| **JWT 鉴权** | Rust 实现,路由级 `auth_required` 控制 | +| **Argon2id 密码哈希** | Rust 实现的高性能密码安全方案 | +| **异步 SQLite** | aiosqlite + SQLModel,多进程并发安全 | +| **本地文件存储** | 内置文件上传/下载端点 | +| **流媒体代理** | ffmpeg + MediaMTX RTSP 流转发 | +| **构建打包** | PyInstaller / Nuitka 一键打包为独立可执行文件 | +| **Vue 3 前端** | Element Plus UI、Pinia 状态管理、类型安全的 API 客户端 | --- @@ -27,20 +30,21 @@ ```text chongming-zenoh/ -├── config.toml # 应用主配置(含 MQTT、Zenoh、DB 等) -├── pyproject.toml # 项目依赖与工具配置 +├── config.toml # 应用主配置 +├── pyproject.toml # 项目依赖与脚本入口 ├── config/ # 配置文件目录 │ ├── zenoh_config.json5 # Zenoh 会话配置 │ └── workers/ # Worker 路由定义(TOML) │ ├── config.toml # 插件注册列表 │ ├── auth/ # 鉴权插件(login / register / me / …) │ ├── doubao/ # 豆包视觉理解插件 -│ └── example/ # 示例插件(add / heartbeat / …) +│ ├── aibox_sophon_adapter/ # AI Box 设备心跳监控插件 +│ └── example/ # 示例插件(四则运算 / MQTT 端点) ├── src/ │ ├── chongming/ # 核心应用 │ │ ├── app/ │ │ │ ├── core/ # WorkerManager, RouteGenerator, MQTTBridge, auth -│ │ │ └── routes/ # 内置路由(存储上传等) +│ │ │ └── routes/ # 内置路由(文件上传等) │ │ └── scripts/ # build, gen_models │ ├── chongming-web/ # Vue 3 前端 │ │ └── src/ @@ -49,18 +53,26 @@ chongming-zenoh/ │ │ └── router/ # Vue Router 配置 │ └── plugins/ # Worker 插件源码 │ ├── auth/ # JWT 鉴权 -│ ├── doubao/ # 豆包 AI -│ └── example/ # 示例(含 MQTT 端点) -├── utils/ # 7 个独立工具包 -│ ├── config/ database/ jwt/ lock/ -│ ├── password/ request/ worker/ -├── test_mqtt_e2e.py # MQTT 端到端测试脚本 -├── publisher.py # MQTT 发布示例 -├── subscriber.py # MQTT 订阅示例 -├── test_amqtt.py # amqtt Broker 独立测试 -├── data/storage/chongming/ # 本地数据存储 +│ ├── doubao/ # 豆包 AI(支持 AICC 安全通道) +│ ├── aibox_sophon_adapter/ # 设备心跳 + 告警 +│ └── example/ # 演示示例 +├── utils/ # 独立工具包 +│ ├── bytedance/ # 字节跳动安全通信 SDK +│ ├── config/ # TOML 配置加载 +│ ├── database/ # 异步 SQLite 封装 +│ ├── jwt/ # Rust JWT 编解码 +│ ├── password/ # Rust Argon2id 哈希 +│ ├── request/ # Zenoh RPC 客户端 +│ ├── stream_manager/ # ffmpeg RTSP 流管理 +│ └── worker/ # Worker 框架核心 +├── data/ +│ ├── storage/chongming/ # SQLite 数据库文件 +│ └── uploads/ # 文件上传目录 ├── logs/ # 日志目录 -└── resources/ # 模块银行打包资源 +├── resources/ # 模块银行打包资源 +├── test_mqtt_e2e.py # MQTT 端到端测试 +├── publisher.py / subscriber.py # MQTT 收发示例 +└── README.md ``` --- @@ -73,27 +85,32 @@ chongming-zenoh/ - Rust 工具链(用于编译 `jwt` / `password` 扩展) - Node.js >= 22(前端开发) - [uv](https://docs.astral.sh/uv/) 包管理器 +- ffmpeg(可选,stream_manager 需要) ### 安装与启动 ```bash -uv sync # 安装依赖 + 编译 Rust 扩展 -uv run serve # 启动服务(开发模式,热重载) +# 同步依赖(自动编译 Rust 扩展 + 安装 Python 包) +uv sync + +# 启动服务(开发模式,热重载) +uv run serve ``` -服务启动后可用: +服务启动后: -| 通道 | 地址 | 说明 | -| ------- | ---------------------------- | ------------------------ | -| HTTP | `http://localhost:8000` | REST API + Swagger 文档 | -| MQTT | `mqtt://localhost:1883` | 内嵌 Broker,Worker 桥接 | -| Swagger | `http://localhost:8000/docs` | OpenAPI 文档 | +| 通道 | 地址 | 说明 | +| ------- | ---------------------------- | ---------------- | +| HTTP | `http://localhost:8000` | REST API | +| Swagger | `http://localhost:8000/docs` | OpenAPI 交互文档 | +| MQTT | `mqtt://localhost:1883` | 内嵌 Broker | ### 前端开发 ```bash cd src/chongming-web -npm install && npm run dev # http://localhost:5173 +npm install +npm run dev # http://localhost:5173 ``` --- @@ -102,201 +119,188 @@ npm install && npm run dev # http://localhost:5173 ```mermaid graph TB - HTTP[HTTP 客户端] -->|REST API| FastAPI[FastAPI 路由
自动生成] - MQTT[MQTT 客户端] -->|chongming/+/+| Bridge[MQTT Bridge
内嵌 Broker] + HTTP[HTTP 客户端] -->|REST API| FastAPI[FastAPI 路由
TOML 自动生成] + MQTT[MQTT 客户端] -->|chongming/+/+| Bridge[MQTT Bridge
纯客户端模式] - FastAPI --> WM[WorkerManager] + FastAPI --> WM[WorkerManager
随机负载均衡 + 超时重试] Bridge --> WM WM -->|Zenoh Query| W1[Worker 副本 1] - WM -->|负载均衡| W2[Worker 副本 2] - WM -->|超时重试| W3[Worker 副本 N] + WM -->|Zenoh Query| W2[Worker 副本 2] + WM -->|Zenoh Query| W3[Worker 副本 N] W1 & W2 & W3 -->|插件业务逻辑| DB[(SQLite)] W1 & W2 & W3 -->|AI 调用| AI[豆包 API] ``` -启动流程: +**启动流程**: ``` uv run serve → FastAPI lifespan: - 1. setup_storage() — 本地文件系统存储 - 2. setup_zenoh() — Zenoh peer 会话 - 3. setup_worker_manager() — WorkerManager + liveliness 刷新 - 4. load_workers() — 动态 import 插件 → 启动 Worker 协程 - 5. register_routes() — 扫描 config/workers/ 生成 HTTP 路由 - 6. setup_mqtt() — 内嵌 Broker + MQTT→Worker 桥接 + 1. setup_storage() — 本地文件系统存储 + 2. setup_zenoh() — Zenoh peer 会话 + 3. setup_worker_manager() — WorkerManager + 定期 liveliness 刷新 + 4. load_workers() — 动态 import 插件 → 启动 Worker 协程 + 5. register_routes() — 扫描 config/workers/ 生成 HTTP 路由 + 6. setup_mqtt() — 内嵌 Broker(子进程)+ MQTT Bridge ``` --- -## MQTT 集成 +## 端点类型与路由注册 -### 协议约定 - -| 方向 | Topic | Payload | -| ---- | -------------------------------- | ------------------------------------------ | -| 请求 | `chongming//` | `{"_method":"MQTT","param1":"value1",...}` | -| 响应 | `chongming///response` | 由 Worker 返回(`None` 则跳过) | - -### 快速测试 - -```bash -# 终端 1: 启动服务 -uv run serve - -# 终端 2: 端到端测试 -python test_mqtt_e2e.py - -# 或手动测试 -python subscriber.py # 监听所有响应 -python publisher.py example add '{"a":3,"b":5,"_method":"MQTT"}' # 有响应 -python publisher.py example heartbeat '{"worker_id":"node-1","_method":"MQTT"}' # 无响应 -``` - -### 无响应模式(心跳上报等) - -Worker 返回 `None` 时,MQTT Bridge 自动跳过响应发布: - -```python -@rpc_method(subject="example.heartbeat", method="MQTT") -async def heartbeat(worker_id: str = "") -> None: - return None # Bridge 跳过发布 -``` - -### 配置 - -```toml -# config.toml — 按环境区分 -[development.mqtt] -enabled = true # false 禁用 MQTT -host = "localhost" -port = 1883 - -[development.mqtt.broker] -# 可选:amqtt Broker 高级参数 -``` - ---- - -## 开发指南 - -### 端点类型说明 +### 端点类型 TOML 文件中的节类型决定端点暴露方式: -| 节类型 | HTTP 路由 | OpenAPI | MQTT | 请求模型命名 | 备注 | -| -------- | --------- | ------- | ---- | ------------------------- | ------------------- | -| `[GET]` | ✅ | ✅ | ✅ | `XxxGetRequest/Response` | | -| `[POST]` | ✅ | ✅ | ✅ | `XxxPostRequest/Response` | | -| `[MQTT]` | ❌ | ❌ | ✅ | `XxxMqttRequest` | 无 `response_model` | - -```toml -# config/workers/example/add.toml -[GET] -summary = "Add via HTTP GET" -params = ["a: float", "b: float"] - -[POST] -summary = "Add via HTTP POST" -params = ["a: float", "b: float"] - -[MQTT] -summary = "Add via MQTT" -params = ["a: float", "b: float"] -``` +| 节类型 | HTTP 路由 | OpenAPI 文档 | MQTT | 请求模型命名 | +| -------- | --------- | ------------ | ---- | ------------------------------------- | +| `[GET]` | ✅ | ✅ | ✅ | `XxxGetRequest / XxxGetResponse` | +| `[POST]` | ✅ | ✅ | ✅ | `XxxPostRequest / XxxPostResponse` | +| `[MQTT]` | ❌ | ❌ | ✅ | `XxxMqttRequest`(无 response_model) | ### 两种路由注册方式 -本项目支持两种路由注册方式,根据场景选用: - #### 方式一:TOML 动态路由(标准 JSON 端点) -通过 `config/workers/<插件>/*.toml` 定义 `[GET]` / `[POST]` 节,网关自动生成 FastAPI 路由。 -适用于参数和响应可被 Pydantic 模型描述的标准 JSON 接口。 - -- 路由生成流程:`TOML 配置 → 自动生成 Pydantic 模型 → 注册 FastAPI 路由` -- 底层 RPC:`FastAPI 路由 → WorkerManager.call() → Zenoh Query → Worker @rpc_method → 响应` +通过 `config/workers/<插件>/*.toml` 定义端点,自动生成 FastAPI 路由。适用于参数和响应可被 Pydantic 模型描述的标准接口。 ```toml # config/workers/example/add.toml [GET] -summary = "加法" +summary = "加法运算" params = ["a: float", "b: float"] + [GET.response_model] result = { type = "float", required = true } ``` #### 方式二:插件自定义路由(特殊端点) -当端点无法用 TOML 描述时(如 `multipart/form-data` 文件上传),插件可在模块顶层暴露 -一个 `APIRouter` 实例,网关在 `load_workers()` 阶段自动发现并注册(无需修改网关代码)。 - -**约定**:插件模块(`__init__.py`)需导入并暴露一个名为 `router` 的 `APIRouter` 实例: - -```python -# src/plugins//__init__.py -from .routes import router # 暴露给网关自动发现 -``` +当端点无法用 TOML 描述时(如 `multipart/form-data` 上传),插件暴露 `APIRouter` 实例,网关自动发现并注册。 ```python # src/plugins//routes.py -from fastapi import APIRouter, UploadFile, File, Form +from fastapi import APIRouter, UploadFile, File router = APIRouter(prefix="/", tags=[""]) @router.post("/upload") -async def upload( - file: UploadFile = File(...), - param1: str = Form(...), -): +async def upload(file: UploadFile = File(...)): ... - return {"result": "ok"} ``` -- 全局前缀(如 `/api/v1`)由网关自动注入,插件无需关心 -- tags 应与 TOML 自动生成的端点保持一致(使用 worker_type) -- TOML 配置中对应端点应设 `internal = true`,避免重复注册 +> **约定**:插件 `__init__.py` 中导入 `router` 实例(`from .routes import router`),网关通过 `getattr(module, "router", None)` 自动发现。 -### HTTP / MQTT 调用路径 +--- -同一端点通过**不同通道**到达 Worker 的路径对比: +## MQTT 协议 -| 通道 | 调用路径 | 适用场景 | -| -------- | --------------------------------------------------------------------------------------- | ------------------------------ | -| **HTTP** | `客户端 → FastAPI 路由 → WorkerManager.call() → Zenoh Query → Worker` | REST API、Web 前端、文件上传 | -| **MQTT** | `MQTT 客户端 → 内嵌 Broker → MQTT Bridge → WorkerManager.call() → Zenoh Query → Worker` | IoT 设备上报、心跳、低带宽环境 | +### Topic 约定 -HTTP 和 MQTT 最终都通过 Zenoh RPC 调用 Worker 的 `@rpc_method` 处理函数,业务逻辑完全共享。 +| 方向 | Topic | 说明 | +| ---- | -------------------------------- | ------------------------------ | +| 请求 | `chongming//` | MQTT → Worker | +| 响应 | `chongming///response` | Worker → MQTT(`None` 时跳过) | +### 快速测试 + +```bash +# 终端 1:启动服务 +uv run serve + +# 终端 2:端到端测试 +python test_mqtt_e2e.py + +# 手动测试 +python subscriber.py # 监听所有响应 +python publisher.py example add '{"a":3,"b":5}' # 调用 add ``` - ┌──────────────────────────────┐ - │ WorkerManager │ - │ (负载均衡 / 超时重试) │ - └──────────┬───────────────────┘ - │ Zenoh Query - ┌──────────▼───────────────────┐ - │ Worker 副本池 │ - │ ┌─────┐ ┌─────┐ ┌─────┐ │ - │ │ W1 │ │ W2 │ │ W3 │ │ - │ └──┬──┘ └──┬──┘ └──┬──┘ │ - │ │ │ │ │ - │ @rpc_method 处理函数 │ - └────────────────────────────────┘ - HTTP 请求到达 ▲ ▲ MQTT 消息到达 - ┌───────┘ └───────┐ - FastAPI 路由(TOML 自动生成) MQTT Bridge - 插件自定义路由(router 约定) (chongming/+/+) -``` + +--- + +## 开发指南 ### 添加新 Worker 插件 -1. 创建 `src/plugins//` — `__init__.py`, `global_var.py`, `router/`, `models/` -2. 注册到 `config/workers/config.toml` -3. 创建 `config/workers//*.toml` 端点定义 -4. `uv run gen_models config/workers// src/plugins//` -5. 实现 `router/.py`,引用生成的模型 -6. 更新 `router/__init__.py` 导入 +```text +1. 创建 src/plugins// — __init__.py, global_var.py, router/, models/ +2. 注册到 config/workers/config.toml 的 [[workers]] +3. 创建 config/workers//*.toml 端点定义 +4. 运行 uv run python -m chongming.scripts.gen_models 生成模型 +5. 实现 router/.py,引用 models/pydantic.py 中的模型 +6. 更新 router/__init__.py 导入 +``` + +### 为现有插件添加新端点 + +```text +1. 创建 config/workers//.toml +2. 运行 uv run python -m chongming.scripts.gen_models +3. 创建 router/.py → 引用生成的模型 +4. 更新 router/__init__.py +5. 重启服务 +``` + +### 常用命令 + +```bash +uv run serve # 启动开发服务 +uv run python -m chongming.scripts.gen_models # 生成 Pydantic 模型 +uv run python -m chongming.scripts.build # 构建打包(PyInstaller/Nuitka) +uv pip install -e utils/ # 安装/更新工具包 +``` + +--- + +## 插件列表 + +| 插件 | 路径 | 功能 | +| ------------------------ | ----------------------------------- | ------------------------------------------------------- | +| **auth** | `src/plugins/auth/` | 用户注册/登录/资料管理,JWT 鉴权,管理员初始化 | +| **doubao** | `src/plugins/doubao/` | 豆包视觉理解,支持 AICC 安全通信通道 | +| **aibox_sophon_adapter** | `src/plugins/aibox_sophon_adapter/` | AI Box 设备心跳监控、离线检测、告警上报与查询、视频上传 | +| **example** | `src/plugins/example/` | 四则运算 + 心跳演示(含 MQTT 端点示例) | + +--- + +## 工具包列表 + +| 包名 | 路径 | 语言 | 说明 | +| ---------------------------- | ----------------------- | ----------- | ---------------------------------------------- | +| **chongming-config** | `utils/config/` | Python | TOML 配置加载,TypedDict 类型安全 | +| **chongming-database** | `utils/database/` | Python | aiosqlite + SQLModel 异步数据库封装 | +| **chongming-jwt** | `utils/jwt/` | Rust + PyO3 | JWT 编解码,支持 HS256/384/512 + RS256/384/512 | +| **chongming-password** | `utils/password/` | Rust + PyO3 | Argon2id 密码哈希与验证 | +| **chongming-request** | `utils/request/` | Python | Zenoh RPC 直连客户端 | +| **chongming-worker** | `utils/worker/` | Python | Worker 框架核心:装饰器、运行时、配置加载 | +| **chongming-stream-manager** | `utils/stream_manager/` | Python | ffmpeg + MediaMTX RTSP 流代理管理 | +| **bytedance** | `utils/bytedance/` | Python | 字节跳动 AICC 安全通信 SDK(Jeddak 等) | + +--- + +## 配置说明 + +- **应用配置**:根目录 `config.toml`,包含环境、服务器、安全、MQTT 等全局设置 +- **Zenoh 配置**:`config/zenoh_config.json5` +- **Worker 注册**:`config/workers/config.toml`,定义加载的插件及其副本数 +- **路由定义**:`config/workers//*.toml`,每个端点一个文件 + +详细配置说明见 [`config/README.md`](config/README.md)。 + +--- + +## 构建部署 + +```bash +# PyInstaller 打包 +uv run python -m chongming.scripts.build pyinstaller + +# Nuitka 打包 +uv run python -m chongming.scripts.build nuitka +``` + +构建过程包括:模块加密打包 → 资源复制 → PyInstaller/Nuitka 打包 → 数据库初始化 → 前端编译 → VFS 挂载。 详见 [插件开发指南](src/plugins/README.md)。 diff --git a/config.toml b/config.toml index 5996b48..ca4b063 100644 --- a/config.toml +++ b/config.toml @@ -73,7 +73,6 @@ base = [ "diskcache", "orjson", "python_multipart", - "modelvault", "volcenginesdkarkruntime", "chongming_jwt", "chongming_database", diff --git a/src/chongming/scripts/build.py b/src/chongming/scripts/build.py index f1b2f99..c99e124 100644 --- a/src/chongming/scripts/build.py +++ b/src/chongming/scripts/build.py @@ -338,16 +338,18 @@ def _stage_nuitka(config: Config) -> tuple[str, str]: "--standalone", "--onefile", "--follow-imports", - "--static-libpython=no", + "--static-libpython=yes", "--remove-output", "--assume-yes-for-downloads", "--lto=yes", + "--pgo-c", + "--pgo-python", "--disable-plugin=tk-inter", - "--disable-plugin=numpy", + "--enable-plugin=numpy", "--output-dir=.", "--output-filename=chongming", "main.py", - "--jobs=2", + "--jobs=4", ] if shutil.which("upx"): cmd.append("--enable-plugin=upx")