9.2 KiB
9.2 KiB
Volcengine Server Manager - 设计文档
日期: 2026-04-04 状态: 待审核
概述
Windows 桌面应用,用于管理火山引擎云服务器 ECS。首期功能:查看服务器状态、重启服务器。
技术栈
| 层 | 选型 | 说明 |
|---|---|---|
| GUI | egui + eframe (glow backend) | 纯 Rust,无外部依赖,单 exe 友好 |
| 火山引擎 API | volcengine-rust-sdk (1.0.2) | crates.io 官方 SDK |
| HTTP | reqwest (SDK 自带) | SDK 内部使用 |
| 异步运行时 | tokio | API 异步调用 |
| 序列化 | serde + serde_json | 配置读写、API 响应解析 |
| 编译目标 | x86_64-pc-windows-gnu | MSYS2 MinGW 工具链 |
配置
配置项
| 配置项 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| access_key_id | String | 空 | 是 | 火山引擎 Access Key ID |
| secret_access_key | String | 空 | 是 | 火山引擎 Secret Access Key |
| endpoint | String | ecs.volcengineapi.com |
否 | ECS API 端点 |
存储方式
- 文件路径:
%APPDATA%\volcengine-server-manager\config.json - 格式: JSON
- 首次启动时检测配置是否存在,不存在则弹出配置弹窗
火山引擎 API 调用
DescribeInstances(查询实例列表)
- 目的: 获取用户账号下所有 ECS 实例
- 请求参数:
MaxResults=100,支持分页 - 响应关键字段:
InstanceId- 实例 IDInstanceName- 实例名称Status- 实例状态(Running, Stopped, etc.)PrivateIpAddresses- 私网 IPPublicIpAddresses- 公网 IPZoneId- 可用区RegionId- 地域InstanceType- 实例规格CreationTime- 创建时间
RebootInstance(重启单台实例)
- 目的: 重启指定 ECS 实例
- 请求参数:
InstanceId(字符串) - 响应: 操作结果
- 注意: 重启前需要用户确认弹窗
区域处理
- 不要求用户手动配置 Region
- 先调用
DescribeRegions获取所有可用区域列表 - 对每个区域并发调用
DescribeInstances获取该区域实例 - 如果
DescribeRegions不可用,则使用常见区域列表硬编码:cn-beijing,cn-shanghai,cn-guangzhou,cn-chengdu,ap-singapore-1
架构设计
模块划分
src/
├── main.rs # 入口:初始化 tokio 运行时,启动 eframe
├── app.rs # egui UI 主逻辑:渲染、事件处理、状态管理
├── config.rs # 配置结构体、JSON 读写
├── api.rs # 火山引擎 API 封装
└── types.rs # 数据类型定义
模块职责
types.rs
InstanceStatus枚举: Running, Stopped, Starting, Stopping, Rebooting, Error, UnknownInstanceInfo结构体: 实例完整信息AppState枚举: Loading, Ready, Error(String)
config.rs
AppConfig结构体: 配置项load_config()->Result<AppConfig>save_config(&AppConfig)->Result<()>- 配置目录:
%APPDATA%\volcengine-server-manager\
api.rs
VolcClient结构体: 封装 SDK Session 或 HTTP 客户端new(access_key_id, secret_access_key, endpoint)-> Selflist_instances()->Result<Vec<InstanceInfo>>reboot_instance(instance_id)->Result<()>- 签名机制: 火山引擎使用 HMAC-SHA256 签名,SDK 不支持时直接构造 HTTP 请求
app.rs
VolcManagerApp结构体: egui App 实现- 状态: instances (Vec), app_state, config, show_config_dialog, selected_instance, loading
update(): UI 渲染主循环- 方法:
refresh_instances(),reboot_selected(),open_config_dialog(),save_config()
main.rs
- 初始化配置
- 创建 tokio 运行时
- 启动 eframe native window
- 设置
windows_subsystem = "windows"去掉控制台
数据流
用户操作 → egui 事件 → App 方法 → tokio spawn 后台任务 → API 调用 → 结果通过 channel 返回 → 更新 state → request_repaint() → UI 刷新
UI 布局
主窗口
┌──────────────────────────────────────────────────────┐
│ 火山引擎服务器管理 [刷新] [⚙ 配置] │
├──────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ 实例名称 │ │ 实例名称 │ │ 实例名称 │ │
│ │ 状态: 运行中 │ │ 状态: 已停止 │ │ 状态: 运行中 │ │
│ │ IP: x.x.x.x │ │ IP: x.x.x.x │ │ IP: x.x.x.x │ │
│ │ 区域: cn-beijing │ 区域: cn-shanghai │ 区域: cn-guangzhou│
│ │ 规格: ecs.g3i.large │ 规格: ... │ 规格: ... │ │
│ │ │ │ │
│ │ [🔄 重启] │ [▶ 启动] │ [🔄 重启] │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
│ ┌────────────┐ ┌────────────┐ │
│ │ ... │ │ ... │ │
│ └────────────┘ └────────────┘ │
│ │
├──────────────────────────────────────────────────────┤
│ 实例数: 5 最后刷新: 2026-04-04 19:30 │
└──────────────────────────────────────────────────────┘
配置弹窗(Modal)
┌────────────────────────────────────┐
│ 配置 │
├────────────────────────────────────┤
│ Access Key ID: │
│ [________________________________]│
│ │
│ Secret Access Key: │
│ [________________________________]│
│ │
│ Endpoint: │
│ [ecs.volcengineapi.com___________]│
│ │
│ [保存] [取消] │
└────────────────────────────────────┘
重启确认弹窗
┌────────────────────────────────────┐
│ 确认重启 │
├────────────────────────────────────┤
│ 确定要重启实例 "xxx" 吗? │
│ 实例 ID: i-xxxxxxxxxxxx │
│ │
│ [确定] [取消] │
└────────────────────────────────────┘
状态颜色映射
| 状态 | 颜色 |
|---|---|
| Running | 绿色 |
| Stopped | 灰色 |
| Starting | 蓝色 |
| Stopping | 橙色 |
| Rebooting | 橙色 |
| Error | 红色 |
| Unknown | 黄色 |
错误处理
- API 调用失败:底部状态栏显示错误信息,3 秒后自动消失
- 配置未设置:首次启动弹出配置弹窗,阻止主界面操作
- 网络异常:显示 "网络连接失败,请检查网络设置"
- 认证失败:显示 "Access Key 或 Secret Key 无效"
中文支持
- 加载 Windows 系统字体
C:\Windows\Fonts\msyh.ttc(微软雅黑) - 通过
egui::FontDefinitions注入为默认字体 - 如果字体加载失败,回退到 egui 内置字体(英文字符)
编译配置
Cargo.toml 关键设置
[package]
name = "volcengine-server-manager"
version = "0.1.0"
edition = "2021"
[[bin]]
name = "volcengine-server-manager"
path = "src/main.rs"
[profile.release]
opt-level = 2
strip = true
lto = true
# Windows 子系统设置(去掉控制台窗口)
[package.metadata.windows]
subsystem = "windows"
实际去掉控制台的方法:在 main.rs 中设置 #![windows_subsystem = "windows"] 属性。
依赖列表
[dependencies]
eframe = { version = "0.29", default-features = false, features = ["glow"] }
egui = "0.29"
volcengine-rust-sdk = "1.0.2"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
dirs = "5"
编译命令
# 在 MSYS2 MinGW 环境下
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
输出文件: target/x86_64-pc-windows-gnu/release/volcengine-server-manager.exe