4e21ca937a
Deploy Documentation / deploy (push) Has been cancelled
Canary / Prepare Version (push) Has been cancelled
Canary / build-cli (push) Has been cancelled
Canary / Upload Install Script (push) Has been cancelled
Canary / bundle-desktop (push) Has been cancelled
Canary / bundle-desktop-intel (push) Has been cancelled
Canary / bundle-desktop-linux (push) Has been cancelled
Canary / bundle-desktop-windows (push) Has been cancelled
Canary / bundle-desktop-windows-cuda (push) Has been cancelled
Canary / Release (push) Has been cancelled
Unused Dependencies / machete (push) Has been cancelled
CI / changes (push) Has been cancelled
CI / Check Rust Code Format (push) Has been cancelled
CI / Build and Test Rust Project (push) Has been cancelled
CI / Build Rust Project on Windows (push) Has been cancelled
CI / Check MSRV (push) Has been cancelled
CI / Lint Rust Code (push) Has been cancelled
CI / Check Generated Schemas are Up-to-Date (push) Has been cancelled
CI / Test and Lint Electron Desktop App (push) Has been cancelled
CI / H5 Plaza Tests and Build (push) Has been cancelled
Live Provider Tests / check-fork (push) Has been cancelled
Live Provider Tests / changes (push) Has been cancelled
Live Provider Tests / Build Binary (push) Has been cancelled
Live Provider Tests / Smoke Tests (push) Has been cancelled
Live Provider Tests / Smoke Tests (Code Execution) (push) Has been cancelled
Live Provider Tests / Compaction Tests (push) Has been cancelled
Live Provider Tests / goose server HTTP integration tests (push) Has been cancelled
Publish Ask AI Bot Docker Image / docker (push) Has been cancelled
Publish Docker Image / docker (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Fork goose with custom MCP widgets, platform extensions (aider, git, web, search), MindSpace H5 backend/frontend, Plaza/Ops UIs, and deploy scripts for tkmind.cn. Co-authored-by: Cursor <cursoragent@cursor.com>
216 lines
9.6 KiB
Markdown
216 lines
9.6 KiB
Markdown
---
|
||
sidebar_position: 2
|
||
title: 系统架构
|
||
sidebar_label: 系统架构
|
||
description: Plaza 的整体架构、技术选型、部署结构和服务边界
|
||
---
|
||
|
||
# 系统架构
|
||
|
||
## 总体架构
|
||
|
||
```text
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ 用户访问层 │
|
||
│ │
|
||
│ 游客/浏览者 登录用户 运营人员 │
|
||
│ /plaza, /u/:slug /space, /chat /ops │
|
||
└───────────┬────────────────────┬──────────────────┬────────────┘
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌───────────────────────────────────────────────────────────────┐
|
||
│ Nginx 统一入口(go.tkmind.cn) │
|
||
│ │
|
||
│ /plaza, /u/ → Next.js :3001 /ops → Ops SPA :3002 │
|
||
│ /api → Node.js :18006 / → H5 SPA :8080 │
|
||
└───────────────────────────┬───────────────────────────────────┘
|
||
│
|
||
┌───────────────┼───────────────┐
|
||
▼ ▼ ▼
|
||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ Plaza 前端 │ │ MindSpace H5 │ │ 运营后台 │
|
||
│ Next.js SSR │ │ Vite CSR │ │ Vite CSR │
|
||
│ ui/plaza/ │ │ ui/h5/ │ │ ui/ops/ │
|
||
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
||
│ │ │
|
||
└────────────────┼────────────────┘
|
||
│ HTTP /api/*
|
||
▼
|
||
┌───────────────────────────────┐
|
||
│ Node.js 后端服务 │
|
||
│ │
|
||
│ /api/mindspace/v1/* │
|
||
│ /api/plaza/v1/* (新增,plaza-*.mjs)│
|
||
│ /api/ops/v1/* (新增,ops-*.mjs) │
|
||
│ /auth/* │
|
||
└───────────────┬───────────────┘
|
||
│
|
||
┌───────────────┼───────────────┐
|
||
▼ ▼ ▼
|
||
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||
│ MySQL │ │ 文件存储 │ │ Redis │
|
||
│ 共用数据库 │ │ 本地/OSS │ │ 热度计数 │
|
||
│ + plaza_*表 │ │ + 缩略图 │ │ + feed缓存 │
|
||
└──────────────┘ └──────────────┘ └──────────────┘
|
||
```
|
||
|
||
## 技术选型
|
||
|
||
### Plaza 前端(ui/plaza/)
|
||
|
||
| 技术 | 选型 | 原因 |
|
||
| --- | --- | --- |
|
||
| 框架 | Next.js 14+ App Router | 原生 SSR/SSG,SEO 最佳实践 |
|
||
| 语言 | TypeScript | 与现有 H5 保持一致 |
|
||
| 样式 | Tailwind CSS | 快速开发,与 H5 互不干扰 |
|
||
| 状态管理 | React Server Components + SWR | 服务端数据优先,客户端增量更新 |
|
||
| 图片优化 | next/image | 自动 WebP、懒加载、尺寸优化 |
|
||
| 分析 | 自建埋点(复用后端 analytics API) | 不依赖第三方 |
|
||
|
||
### 运营后台(ui/ops/)
|
||
|
||
| 技术 | 选型 | 原因 |
|
||
| --- | --- | --- |
|
||
| 框架 | Vite + React | 与 H5 工具链一致,快速启动 |
|
||
| UI 组件库 | 复用现有组件风格 | 不引入新依赖 |
|
||
| 权限 | 独立 ops_role 中间件 | 与普通 admin 权限隔离 |
|
||
|
||
### 后端扩展
|
||
|
||
| 模块 | 实现方式 |
|
||
| --- | --- |
|
||
| Plaza API | 在现有 Node 服务中新增 `/api/plaza/v1/` 路由模块 |
|
||
| 热度计数 | Redis INCR + 定时回写 MySQL |
|
||
| 缩略图生成 | 发布时异步截图任务(Puppeteer worker) |
|
||
| 内容审核队列 | MySQL 任务表(与现有 upload scan 模式一致) |
|
||
|
||
## 服务边界原则
|
||
|
||
### Plaza 可以做的
|
||
|
||
- 读取 `h5_publish_records` 表(逻辑名 *publications*)判断帖子来源是否 `online`。
|
||
- 读取 `h5_users` 表(逻辑名 *users*)获取创作者基础信息(id、slug、display_name、avatar_url)。
|
||
- 在**同一 MySQL 实例**内,通过定时任务将广场计数回写到 `h5_publish_records.plaza_view_count` / `plaza_like_count`(不调用 MindSpace service 函数,但字段由 MindSpace 侧迁移脚本统一定义)。
|
||
|
||
### Plaza 不能做的
|
||
|
||
- 直接 JOIN `h5_user_spaces`、`h5_page_records`、`h5_assets` 等 MindSpace 核心表。
|
||
- 调用 MindSpace 的内部 service 函数(如 `mindspace_service.getPage()`)。
|
||
- 绕过 MindSpace 发布流程直接操作 `publications` 状态。
|
||
|
||
### 跨模块通信方式
|
||
|
||
```text
|
||
Plaza 需要 MindSpace 数据时:
|
||
① 读 plaza_posts 中的冗余快照字段(title, cover_url, user_slug 等)
|
||
② 调用 /api/mindspace/v1/ 公开接口(只读场景)
|
||
③ 通过共用数据库字段或异步任务表传递事件(不 import MindSpace service 模块)
|
||
|
||
MindSpace 下线 publication 时:
|
||
→ 在 mindspace-publications 的同一数据库事务内 UPDATE plaza_posts SET status = 'hidden'
|
||
|
||
Plaza 回写 publication 广场统计时:
|
||
→ 独立定时任务 UPDATE h5_publish_records(见 04-backend-api「互动数据回写」)
|
||
```
|
||
|
||
## 部署结构
|
||
|
||
### 进程列表
|
||
|
||
| 进程 | 端口 | 启动命令 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| Nginx | 443 | systemd | 统一入口,SSL 终止 |
|
||
| Node.js 后端 | 18006 | `node server.mjs` | 现有服务,扩展新路由 |
|
||
| MindSpace H5 | 8080 | `pnpm preview` | 现有 Vite SPA |
|
||
| Plaza Next.js | 3001 | `pnpm start` | 新建,SSR |
|
||
| 运营后台 | 3002 | `pnpm preview` | 新建,CSR SPA,仅内网 |
|
||
| Redis | 6379 | systemd | 新增 |
|
||
|
||
### Nginx 配置核心
|
||
|
||
```nginx
|
||
server {
|
||
server_name go.tkmind.cn;
|
||
|
||
# 广场和用户主页 → Next.js SSR
|
||
location ~ ^/(plaza|u/) {
|
||
proxy_pass http://127.0.0.1:3001;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
}
|
||
|
||
# 运营后台 → 内网限制
|
||
location /ops {
|
||
allow 10.0.0.0/8; # 内网 IP 段
|
||
deny all;
|
||
proxy_pass http://127.0.0.1:3002;
|
||
}
|
||
|
||
# 所有 API → 共用后端
|
||
location /api {
|
||
proxy_pass http://127.0.0.1:18006;
|
||
}
|
||
|
||
# 其余 → MindSpace H5
|
||
location / {
|
||
proxy_pass http://127.0.0.1:8080;
|
||
}
|
||
}
|
||
```
|
||
|
||
### Cookie 共享策略
|
||
|
||
三个前端应用同 host(`go.tkmind.cn`),Nginx 按路径转发到不同端口。**Session Cookie 使用 host-only**(不设置 `Domain` 属性),则 `/`、`/plaza`、`/ops` 天然共享登录态,无需 SSO。
|
||
|
||
```
|
||
Set-Cookie: session_id=xxx; Path=/; HttpOnly; Secure; SameSite=Lax
|
||
```
|
||
|
||
若未来拆到子域(如 `plaza.go.tkmind.cn`),再改为 `Domain=.go.tkmind.cn` 并统一调整各前端 API 基址。
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
ui/
|
||
├── h5/ # 现有 MindSpace,不动
|
||
├── plaza/ # 新建 Next.js 广场
|
||
│ ├── app/
|
||
│ │ ├── plaza/ # 广场首页和分类
|
||
│ │ │ ├── page.tsx # /plaza SSR
|
||
│ │ │ └── cat/[slug]/page.tsx
|
||
│ │ ├── plaza/p/[id]/ # 帖子详情
|
||
│ │ │ └── page.tsx
|
||
│ │ └── u/[slug]/ # 用户主页
|
||
│ │ └── page.tsx
|
||
│ ├── components/
|
||
│ │ ├── PostCard.tsx # 卡片组件
|
||
│ │ ├── PostGrid.tsx # 瀑布流
|
||
│ │ ├── CategoryNav.tsx # 分类导航
|
||
│ │ └── UserProfile.tsx # 用户主页
|
||
│ ├── lib/
|
||
│ │ └── api.ts # 调用 /api/plaza/v1/
|
||
│ └── types/
|
||
│ └── plaza.ts
|
||
└── ops/ # 新建运营后台
|
||
└── src/
|
||
├── pages/
|
||
│ ├── ReviewQueue.tsx
|
||
│ ├── FeaturedManager.tsx
|
||
│ └── Analytics.tsx
|
||
└── api/
|
||
└── client.ts # 调用 /api/ops/v1/
|
||
```
|
||
|
||
## 扩展路径
|
||
|
||
当以下信号出现时,将 Plaza 拆出为独立后端服务:
|
||
|
||
| 信号 | 行动 |
|
||
| --- | --- |
|
||
| 广场流量是 MindSpace 的 10 倍+ | 将 plaza_* 表迁移到独立数据库,后端服务拆分 |
|
||
| 推荐算法需要 Python ML 服务 | 新建推荐微服务,后端调用其接口 |
|
||
| 内容审核需要独立合规团队 | 运营后台独立部署,API 拆分 |
|
||
| 广场开放第三方内容(非 MindSpace) | 数据模型不再依赖 publications 外键,彻底解耦 |
|
||
|
||
拆分时要搬走的只有:`plaza_*` 表、`/api/plaza/v1/` 路由、`ui/plaza/`,其他不动。
|