文档状态:产品与技术路线图,不是当前实现规范。
当前实现以 文档首页、架构文档、配置参考、API 参考 和代码为准。
更新日期:2026-07-22
| 能力 | 当前状态 |
|---|---|
| 一个 Java 与一个基岩版入口 | 已实现 |
| 独立 Web + Monitor + SQLite WAL | 已实现 |
| 60 秒默认检测、3 次失败/2 次恢复 | 已实现 |
| 在线人数趋势与 30 格可用性条 | 已实现 |
| 手动临时检查与 SVG 状态标签 | 已实现 |
| 多服务器模型、事件系统、管理后台 | 未实现 |
| 通知、订阅、多探测点、深度指标 | 未实现 |
| PostgreSQL 迁移 | 未来方向 |
以下内容保留为未来设计参考。表、接口、目录与验收项除非在“当前实现对照”中标记为已实现,否则均不代表当前代码能力。
为玩家提供一个独立于 Minecraft 游戏服的公开状态页,让玩家可以快速回答以下问题:
| 方案 | 优点 | 缺点 | 结论 |
|---|---|---|---|
| 静态网页直接调用第三方状态 API | 开发最快、无需后端 | 受第三方限流和故障影响;难以形成可信历史;浏览器跨域受限 | 只适合原型 |
| 自建协议探测器 + 状态 API + 历史库 | 数据可控;可记录可用率;Java/基岩版都可扩展 | 需要运行一个常驻探测服务 | MVP 推荐 |
| 游戏服插件/Agent + 监控平台 | 可获取 TPS、资源使用等深度指标 | 耦合游戏服;部署和权限更复杂 | 第二阶段按需增加 |
Next.js 官方支持 Node.js 和 Docker 自托管;生产环境在应用前放置反向代理,可负责 TLS、请求限制和异常请求防护。探测器需要访问 Java 版 TCP 端口和基岩版 UDP 端口,因此不应默认部署到限制原始 TCP/UDP 出站连接的纯静态或 Edge 环境。
首期只需要一个公开首页,详情通过卡片和可展开区域呈现;服务器较多时再增加独立详情页。
┌──────────────────────────────────────────────────────┐
│ Logo / 服务器名称 [全部系统正常 ●] │
├──────────────────────────────────────────────────────┤
│ 当前状态概览 │
│ “所有服务器均可正常加入” 最后更新 12:30 │
├──────────────────────────────────────────────────────┤
│ Java 生存服 在线 │
│ play.example.com [复制] │
│ 18 / 100 玩家 1.21.x 42 ms │
│ MOTD │
│ [最近 24h 延迟折线] [最近 30 天可用状态条] │
├──────────────────────────────────────────────────────┤
│ 基岩版入口 维护中 │
│ bedrock.example.com:19132 [复制] │
├──────────────────────────────────────────────────────┤
│ 事件记录 │
│ 07-20 网络波动(已恢复) │
│ 07-25 计划维护(计划中) │
├──────────────────────────────────────────────────────┤
│ 帮助 / 社区链接 / 状态说明 / 隐私说明 │
└──────────────────────────────────────────────────────┘
prefers-reduced-motion,状态变化不使用持续闪烁动画。Java 版使用 Server List Ping,经 TCP 获取:
基岩版通过 UDP/RakNet 未连接 Ping 获取:
| 项目 | MVP 默认值 | 说明 |
|---|---|---|
| 检测周期 | 60 秒 | 每台服务器加入 0~10 秒随机抖动 |
| 单次超时 | 5 秒 | DNS、连接和协议读取都必须有上限 |
| 并发数 | 5 | 防止配置错误时耗尽连接资源 |
| 判定离线 | 连续 3 次失败 | 过滤短暂丢包,约 3 分钟后确认 |
| 判定恢复 | 连续 2 次成功 | 避免在线/离线反复抖动 |
| 数据过期 | 超过 3 个检测周期 | 标记“未知”,不把旧数据伪装为在线 |
| 原始数据保留 | 90 天 | 后续按天聚合后可清理 |
超时、DNS 失败、拒绝连接、协议异常需要保存为不同错误码,但公开页面只展示适合玩家理解的文案,详细错误保留在日志中。
stateDiagram-v2
[*] --> UNKNOWN
UNKNOWN --> OPERATIONAL: 首次探测成功
UNKNOWN --> OUTAGE: 连续 3 次失败
OPERATIONAL --> DEGRADED: 高延迟或部分入口失败
OPERATIONAL --> OUTAGE: 连续 3 次失败
DEGRADED --> OPERATIONAL: 连续 2 次恢复
DEGRADED --> OUTAGE: 连续 3 次失败
OUTAGE --> OPERATIONAL: 连续 2 次成功
OPERATIONAL --> MAINTENANCE: 到达计划维护时间
DEGRADED --> MAINTENANCE: 到达计划维护时间
OUTAGE --> MAINTENANCE: 人工标记维护
MAINTENANCE --> OPERATIONAL: 维护结束且连续 2 次成功
MAINTENANCE --> OUTAGE: 维护结束但仍探测失败
建议首期将“性能下降”定义为以下任一条件:
阈值应按探测机与游戏服的实际网络距离调整,不能把一个全球统一延迟值写死。
可用率 = 成功检测次数 / 有效检测总次数 × 100%
flowchart LR
U["玩家浏览器"] --> P["Caddy / Nginx\nTLS + 限流"]
P --> W["Next.js Web\n页面 + 只读 API"]
W --> DB[("SQLite / PostgreSQL")]
M["Node.js Monitor Worker"] -->|"TCP Server List Ping"| J["Java 服务器"]
M -->|"UDP RakNet Ping"| B["基岩版服务器"]
M --> DB
M --> N["可选通知渠道"]
A["管理员配置"] --> M
A --> W
check_results。server_snapshots,必要时创建或解决自动故障事件。Minecraft-Server-Status/
├─ apps/
│ ├─ web/ # Next.js 页面与只读 API
│ └─ monitor/ # 定时探测 Worker
├─ packages/
│ ├─ core/ # 状态枚举、规则、共享类型
│ ├─ database/ # Schema、迁移、查询
│ └─ config/ # 环境变量与服务器配置校验
├─ docs/
├─ deploy/
│ ├─ compose.yaml
│ └─ Caddyfile
├─ .env.example
└─ README.md
servers| 字段 | 类型 | 说明 |
|---|---|---|
id |
UUID/Text | 主键 |
slug |
Text Unique | URL 和稳定标识 |
name |
Text | 展示名称 |
edition |
Enum | JAVA / BEDROCK |
host |
Text | 实际探测主机,仅服务端可见 |
port |
Integer | 探测端口 |
display_address |
Text | 玩家复制的地址 |
enabled |
Boolean | 是否启用探测与展示 |
sort_order |
Integer | 页面排序 |
created_at / updated_at |
DateTime | 审计字段 |
check_results| 字段 | 类型 | 说明 |
|---|---|---|
id |
Integer/BigInt | 主键 |
server_id |
Foreign Key | 对应服务器 |
checked_at |
DateTime | 检测时间,统一存 UTC |
success |
Boolean | 协议探测是否成功 |
latency_ms |
Integer Nullable | 成功时的延迟 |
players_online / players_max |
Integer Nullable | 玩家数 |
version_name / protocol |
Text/Integer Nullable | 版本信息 |
motd |
JSON/Text Nullable | 安全标准化后的 MOTD |
favicon_hash |
Text Nullable | 图标变化标识,图标本体去重保存 |
error_code |
Text Nullable | 标准化错误类型 |
server_snapshots每台服务器一行,保存当前状态、连续成功/失败次数、最后成功时间、最近错误和最新展示数据。首页只读取此表,避免每次请求扫描历史数据。
daily_stats按服务器和 UTC 日期聚合成功、失败、维护、未知次数,以及平均、P50、P95 延迟。页面再根据访问者时区格式化标签。
incidents 与 incident_updates所有公开接口只读,不接受用户提供的 host 或 port。
GET /api/v1/status返回首页首屏所需的完整快照,减少浏览器请求数。
{
"overallStatus": "OPERATIONAL",
"checkedAt": "2026-07-21T04:30:00Z",
"stale": false,
"servers": [
{
"slug": "survival-java",
"name": "Java 生存服",
"edition": "JAVA",
"status": "OPERATIONAL",
"displayAddress": "play.example.com",
"version": "1.21.x",
"players": { "online": 18, "max": 100 },
"latencyMs": 42,
"motd": [{ "text": "欢迎来到生存服", "color": "green" }]
}
],
"activeIncidents": []
}
GET /api/v1/servers/{slug}/history?range=24h|7d|30dGET /api/v1/incidents?status=active|resolved&limit=20GET /api/health/live:Web 进程存活。GET /api/health/ready:数据库迁移完成且可读取。历史接口限制时间范围和最大点数,由服务端降采样,避免返回无限数据。
状态页也可能故障,因此需要记录:
首期可以用结构化日志和简单健康检查;规模扩大后再接 Prometheus/Alertmanager。告警应针对玩家可感知症状,并设置持续时间,避免一次丢包就通知管理员。
proxy、web、monitor,SQLite 数据放持久卷。status.example.com。APP_BASE_URL=https://status.example.com
DATABASE_URL=file:/data/status.db
CHECK_INTERVAL_SECONDS=60
CHECK_TIMEOUT_MS=5000
DOWN_AFTER_FAILURES=3
UP_AFTER_SUCCESSES=2
HISTORY_RETENTION_DAYS=90
服务器列表建议使用受版本控制的 YAML/JSON 配置,真实 host 可以从环境变量注入;公开 API 只返回 displayAddress。
在服务器资料和部署环境明确、首期不做管理后台的情况下,MVP 预计约 3.5~4.5 个开发日。视觉定制、通知渠道和复杂代理拓扑需要另外评估。
若暂时没有额外偏好,建议直接按以下基线进入开发: