lightning-sagar/BetterStack
GitHub: lightning-sagar/BetterStack
一个基于 Rust 和 TurboRepo 构建的弹性网站监控系统,通过解耦队列架构持续跟踪服务可用性和响应时间,并以现代化仪表板展示监控数据与事件。
Stars: 0 | Forks: 0
# BetterStack:弹性的网站监控系统
## 引言
BetterStack 是一个弹性的网站监控系统,旨在跟踪服务可用性、测量响应时间、存储健康检查结果,并通过现代化的仪表板展示突发事件。该项目由多个部分组成,具体包括:
- 用于高性能服务组件的 Rust 后端工作区
- 基于 TurboRepo 的前端和 JavaScript 服务层,用于仪表板、API、队列生产者和工作者
- 用于持久化监控数据的 PostgreSQL
- 用于在生产者和工作者之间进行解耦任务投递的 Redis Streams
该系统会持续检查已注册网站的上线或下线状态,将每次结果记录为一次“心跳”,并通过前端仪表板向用户和运维人员展示数据。
## 动机
2022 年 6 月,一次重大的 Cloudflare 宕机事件影响了全球数以千计的网站和服务。从这类事件中得出一个关键教训很简单:如果监控平台依赖于同样出现故障的基础设施,那么服务本身和监控系统可能会同时崩溃。在这种情况下:
- 没有告警
- 没有通知
- 没有可见性
本项目的动机源于构建一个在服务中断期间仍然能够发挥作用的监控平台的需求。BetterStack 没有依赖单一的紧密耦合组件,而是采用了基于队列的架构,结合专用工作者、持久化存储和独立的健康检查,以提高系统的弹性和可观测性。
## 问题陈述
现代应用程序依赖于云平台、API、数据库和分布式基础设施。当某个服务发生故障时:
- 企业会损失收入
- 用户会失去信任
- 工程师会因为缺乏及时信号而滞后响应
许多团队依赖第三方的监控平台,但这些系统本身也可能发生故障或变得不可访问。BetterStack 通过设计一个持续收集可用性数据、异步推送检查并将结果存储起来以供后续告警、分析和事件展示的监控工作流,解决了这一问题。
## 目标
- 7x24 小时监控网站和服务端点
- 快速检测停机和延迟劣化
- 存储健康检查历史记录以供分析
- 支持基于工作者的分布式监控
- 使用 Redis Streams 将数据生产与处理过程分离
- 提供用于展示网站、状态和突发事件的前端仪表板
- 减少监控管道中的单点故障
## 系统概述
BetterStack 目前包含两个主要的实现部分:
### 1. Rust 后端工作区
位于 `BetterStack_Rust/` 目录下,该工作区包含专注于性能、持久化和工作者处理的 Rust 服务。
- `api`:使用 Poem 构建的 HTTP API
- `store`:使用 Diesel 和 PostgreSQL 的共享数据库层
- `worker`:消费 Redis Stream 任务、发送 HTTP 请求并存储心跳的后台监控器
- `redis`:共享的 Redis Stream 辅助工具
- `pusher`:用于分发工作的面向队列的服务脚手架
### 2. TurboRepo 前端和 JS 服务
位于 `BetterStack_turbo/` 目录下,这个 monorepo 包含了仪表板前端和 TypeScript/Bun 服务层。
- `apps/my-app`:Next.js 前端仪表板
- `apps/api`:用于身份验证、网站、告警和状态端点的 Express API
- `apps/pusher`:将网站任务推送到 Redis Streams 的生产者
- `apps/worker`:消费任务并存储心跳的工作者
- `packages/store`:共享的 Prisma 客户端和 schema
- `packages/redis-stream`:Redis 工具包
- `packages/ui`:可复用的 UI 组件
## 后端架构
### Rust 后端
Rust 实现主要围绕性能和可靠性进行设计。
- 在 Rust API 中使用 `Poem` 作为 HTTP 服务器和路由。
- `Tokio` 为异步执行和工作者并发提供支持。
- `Diesel` 负责 PostgreSQL ORM 和 schema 管理。
- 工作者使用 `Reqwest` 执行端点检查。
- `Redis Streams` 将网站调度与处理过程解耦。
当前 Rust 流程:
1. 通过 API 注册一个网站。
2. 网站数据存储在 PostgreSQL 中。
3. 任务被放入 Redis Streams 中。
4. Rust 工作者消费待处理的任务。
5. 每个工作者向目标端点发送一个 HTTP 请求。
6. 工作者将响应时间和状态(`Up`、`Down` 或 `Unknown`)记录到数据库中。
### TurboRepo 前端和服务层
TurboRepo 提供了仪表板和平台的 JavaScript 运行时实现。
- `Next.js` 用于面向用户的前端。
- `React` 驱动仪表板 UI。
- `Tailwind CSS` 为前端提供样式。
- `Express` 暴露用于身份验证和网站管理的后端 HTTP API。
- `Bun` 用于运行 API、pusher 和 worker 服务。
- `Prisma` 为 PostgreSQL 提供共享的数据库客户端。
- `Zustand` 用于前端状态管理。
当前前端/服务层功能包括:
- 着陆页
- 登录流程
- 仪表板视图
- 网站详情视图
- 事件页面
- 设置页面
- 经过身份验证的网站 CRUD 操作
- 状态和心跳历史检索
## 数据流
监控管道可以概括为:
1. 用户从前端仪表板注册一个网站。
2. API 存储该网站及其所有权元数据。
3. Pusher 读取网站并将监控任务添加到 Redis Streams。
4. 工作者消费排队中的任务。
5. 工作者请求端点并计算响应时间。
6. 工作者将心跳数据存储在 PostgreSQL 中。
7. 仪表板获取网站和心跳历史记录以进行可视化展示。
## 文献综述
可靠的监控系统是分布式系统工程的核心组成部分。先前的研究和行业指南一致表明,监控必须是实时的、告警驱动的,并且能够抵御基础设施级别的故障。
Google 的 SRE 指南区分了白盒监控和黑盒监控,并强调黑盒检查至关重要,因为它们验证的是用户可见的系统行为,而不仅仅是内部指标。这与 BetterStack 通过请求端点并测量实际服务响应能力的模型直接契合。
研究和运维报告也表明,故障并不总是彻底的停机。许多生产系统在全盘崩溃之前,会经历执行缓慢、部分中断或响应劣化的情况。因此,监控系统应该同时捕获可用性和延迟,而不仅仅是二元的 up/down 状态。
2022 年的 Cloudflare 宕机事件进一步说明了独立可观测性的重要性。如果组织依赖紧密耦合的监控设置,重大的基础设施事件可能会剥夺他们检测和响应故障所需的可见性。BetterStack 正是受到这一痛点的启发,采用了解耦的生产者-工作者-存储架构以提高系统的弹性。
## 工具和技术
### 后端
| 工具 / 技术 | 用途 |
| --- | --- |
| Rust | 用于后端服务的系统编程语言 |
| Poem | HTTP 服务器和路由 |
| Tokio | 异步运行时 |
| Diesel | PostgreSQL 的 ORM |
| PostgreSQL | 持久化数据存储 |
| Redis Streams | 基于队列的任务投递 |
| Reqwest | 端点健康检查 |
| Dotenvy | 环境变量加载 |
| UUID / Chrono | ID 生成和时间戳 |
### 前端和服务层
| 工具 / 技术 | 用途 |
| --- | --- |
| TurboRepo | Monorepo 编排 |
| Next.js | 前端框架 |
| React | UI 库 |
| Tailwind CSS | 样式 |
| TypeScript | 类型安全的应用程序代码 |
| Bun | 用于 API、worker 和 pusher 的运行时 |
| Express | REST API 层 |
| Prisma | 数据库客户端和 schema 管理 |
| PostgreSQL | 共享的关系型数据库 |
| Redis | 消息流传输 |
| Zustand | 客户端状态管理 |
| Radix UI / Lucide React | UI 原语和图标 |
## 数据库模型
TurboRepo 中的共享 schema 和 Rust store 层都反映了核心的监控实体:
- `User`:存储身份验证和所有权数据
- `Website`:存储被监控的 URL
- `Region`:标识位置或工作者区域
- `WebsiteTick`:存储响应时间、状态码和检查时间戳
这种结构支持历史监控、单站点分析,并为未来版本中的多区域扩展提供了可能。
## 主要特性
- 用户注册和身份验证
- 网站注册和所有权映射
- 定期网站健康检查
- 使用 Redis Streams 的基于队列的处理
- 在 PostgreSQL 中存储延迟和状态信息
- 面向突发事件和仪表板的前端
- Rust 和 TurboRepo 实现中的模块化后端结构
## 为什么这种设计很重要
这种架构在以下几个方面提高了弹性:
- 生产者和工作者是解耦的,因此即使某个服务重启,检查仍能继续进行。
- 结果会被持久化,从而保留了历史可见性。
- 工作者可以水平扩展以应对更大的监控负载。
- 前端与检查执行管道保持分离。
- 该设计支持未来的扩展,例如告警、重试、基于区域的检查和状态页生成。
## 建议的未来改进
- 电子邮件、短信或 Webhook 告警
- 多区域工作者部署
- SLO/SLA 报告
- 事件时间轴生成
- 重试逻辑和故障分类
- 用于展示正常运行时间百分比和响应时间趋势的图表
- 基于角色的访问控制
- Docker Compose 或 Kubernetes 部署清单
## 仓库结构
```
BetterStack/
|-- Readme.md
|-- BetterStack_Rust/
| |-- api/
| |-- worker/
| |-- store/
| |-- redis/
| `-- pusher/
|-- BetterStack_turbo/
| |-- apps/
| | |-- my-app/
| | |-- api/
| | |-- pusher/
| | `-- worker/
| `-- packages/
| |-- store/
| |-- redis-stream/
| `-- ui/
`-- redis_stream_ex/
```
## 结论
BetterStack 是一个实用的分布式监控平台,它将 Rust 后端实现与基于 TurboRepo 的前端及服务生态系统结合在一起。它解决了一个现实世界中的可靠性问题:即使在部分基础设施承受压力的情况下,监控也必须保持可信。通过结合持久化存储、异步工作者、Redis Streams 和仪表板界面,该项目为弹性的服务监控奠定了坚实的基础。
## 参考文献 (IEEE 格式)
[1] T. Strickx 和 J. Hartman,"2022 年 6 月 21 日 Cloudflare 宕机事件",Cloudflare 博客,2022 年 6 月 21 日。[在线]。可用:https://blog.cloudflare.com/cloudflare-outage-on-june-21-2022/
[2] R. Ewaschuk,"监控分布式系统",载于 *Site Reliability Engineering*,Google SRE。[在线]。可用:https://sre.google/sre-book/monitoring-distributed-systems/
[3] R. Lu 等人,"Perseus:面向云存储系统的执行缓慢检测框架",载于 *21st USENIX Conference on File and Storage Technologies (FAST '23)*,2023 年。[在线]。可用:https://www.usenix.org/conference/fast23/presentation/lu
[4] M. P. Kasick、J. Tan、R. Gandhi 和 P. Narasimhan,"并行文件系统中的黑盒问题诊断",载于 *8th USENIX Conference on File and Storage Technologies (FAST '10)*,2010 年。[在线]。可用:https://www.usenix.org/conference/fast-10/black-box-problem-diagnosis-parallel-file-systems
标签:API集成, Cloudflare宕机, CMS安全, DevOps工具, JavaScript, PostgreSQL, Redis Streams, Rust后端, TurboRepo, Web监控, 事件仪表板, 任务队列, 健康检查, 分布式系统, 可观测性, 可视化界面, 告警通知, 响应大小分析, 响应时间测量, 实时处理, 异步队列, 搜索引擎查询, 无线安全, 服务可用性, 测试用例, 现代化仪表盘, 系统弹性, 网站监控, 自动化攻击, 运维监控, 高可用架构