惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
雷峰网
雷峰网
博客园_首页
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
小众软件
小众软件
D
Docker
P
Proofpoint News Feed
B
Blog
Vercel News
Vercel News
B
Blog RSS Feed
U
Unit 42
月光博客
月光博客
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
I
InfoQ
Recent Announcements
Recent Announcements

唯知笔记

唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站 唯知笔记 | 一个高效的知识分享网站
唯知笔记 | 一个高效的知识分享网站
weizwz@foxma · 2026-02-02 · via 唯知笔记

完全免费的网站状态监控服务 - UptimeFlare ​

UptimeFlare 是一个基于 Cloudflare Workers 的 Serverless 网站状态监控服务,完全免费且易于部署。本文将详细介绍其技术架构、核心功能实现以及开发部署流程。项目 fork 自 lyc8503/UptimeFlare,在原有基础上进行了界面美化和功能优化。在线演示:status.weizwz.com,项目地址:weizwz/UptimeFlare。预览图如下:

技术栈概览 ​

系统架构 ​

整体架构 ​

数据流 ​

  1. 监控流程

    Cron Trigger → Worker 检查 → 更新 D1 → 记录状态/故障
  2. 页面渲染流程

    用户访问 → Pages 请求 → 读取 D1 → SSR 渲染 → 返回 HTML
  3. 实时更新流程

    Worker 定时检查 → 状态变化 → 更新数据库 → 前端轮询/刷新

项目结构 ​

UptimeFlare/
├── components/              # React 组件
│   ├── MonitorCard.tsx     # 监控卡片
│   ├── MonitorDetail.tsx   # 监控详情
│   ├── DetailBar.tsx       # 数据可视化
│   ├── MaintenanceAlert.tsx # 维护通知
│   ├── IncidentsDrawer.tsx # 历史故障侧边栏
│   └── OverallStatus.tsx   # 整体状态

├── pages/                   # Next.js 页面
│   ├── index.tsx           # 主页
│   ├── incidents.tsx       # 历史故障页面
│   └── api/                # API 路由
│       └── data.ts         # 数据接口

├── worker/                  # Cloudflare Worker
│   └── src/
│       ├── index.ts        # Worker 入口
│       ├── monitor.ts      # 监控逻辑
│       ├── store.ts        # 数据存储
│       └── util.ts         # 工具函数

├── locales/                 # 国际化
│   ├── en/                 # 英文
│   ├── zh-CN/              # 简体中文
│   └── zh-TW/              # 繁体中文

├── types/                   # TypeScript 类型
│   └── config.ts           # 配置类型定义

├── uptime.config.ts        # 监控配置
├── wrangler.toml           # Worker 配置
├── next.config.js          # Next.js 配置
└── package.json            # 依赖管理

开发指南 ​

1. 安装依赖 ​

2. 监控配置项 ​

重要

uptime.config.ts 里的监控服务 monitors 建议首次就配置好,尤其是里面的 id,多次修改会造成脏数据。所有配置项都可以参考 uptime.config.full.ts 文件

uptime.config.ts

typescript

const pageConfig: PageConfig = {
  // 标题
  title: '服务状态 - weizwz',
  // 分组,根据 monitors 里的服务 id
  group: {
    基础服务: ['weiwz', 'blog', 'picture'],
    实用工具: ['nav', 'cover'],
    演示项目: ['fun_animation', 'charts']
  }
}
export const workerConfig = {
  monitors: [
    {
      id: 'blog', // 唯一标识,不要随意修改
      name: '博客',
      method: 'HEAD',
      target: 'https://note.weizwz.com/', // 必需,监控 url
      statusPageLink: 'https://note.weizwz.com/', // 项目点击链接,有了之后界面可以点击跳转
      preview: 'https://p.weizwz.com/siteshot_note.webp' // 监控项目主页预览图,非必须
    }
  ],
  notification: {
    webhook: {
      // 通知必需,建议去 `https://resend.com/` 注册,免费。后面有具体教程
      url: 'https://api.resend.com/emails',
      payload: {
        from: '系统状态更新 <uptimeflare@updates.weizwz.com>', // 你的线上监控服务域名
        to: ['xxxxxx@gmial.com'], // 你的邮箱
        subject: 'UptimeFlare 状态更新',
        text: '$MSG'
      }
    }
  }
}
// 公告,非必须
const maintenances: MaintenanceConfig[] = [
  // {
  //   title: '图床服务维护',
  //   body: '正在进行图床服务器升级维护,预计2小时完成',
  //   monitors: ['picture'],
  //   start: '2026-02-01T18:00:00+08:00',
  //   end: '2026-02-21T23:00:00+08:00',
  // },
]

3. 本地数据库初始化 ​

重要说明

  • 数据库文件自动创建:首次运行 npm run dev 时,Wrangler 会自动在 .wrangler/state/v3/d1/ 目录创建 SQLite 数据库文件
  • ⚠️ 表结构需要手动创建:数据库文件虽然自动创建,但 uptimeflare 表需要手动执行 SQL 创建
  • ⚠️ 数据需要手动导入:表创建后,需要手动插入初始数据或从生产环境导入

步骤 3.1:启动开发服务器

bash

npm run dev
# 此时会自动创建数据库文件,但表结构未创建,页面无数据
# 访问 http://localhost:3000

步骤 3.2:创建表结构

bash

# 使用 init.sql 初始化表结构
npx wrangler d1 execute UPTIMEFLARE_D1 --local --file=./init.sql

步骤 3.3:初始化数据

选择以下任一方式:

  1. 手动插入空数据(首次部署)

bash

# 插入空的初始状态
npx wrangler d1 execute UPTIMEFLARE_D1 --local \
  --command "INSERT INTO uptimeflare (key, value) VALUES ('state', '{\"overallUp\":0,\"overallDown\":0,\"lastUpdate\":0,\"incident\":{},\"latency\":{}}')"
  1. 导出远程数据到本地开发环境

查询远程数据库名称,运行 npx wrangler d1 list
在项目根目录运行以下命令导出数据(请将 <YOUR_DB_NAME> 替换为实际名称):

bash

npx wrangler d1 execute <YOUR_DB_NAME> \
  -c /dev/null \
  --remote \
  --command "SELECT value FROM uptimeflare WHERE key = 'state'" \
  --json > backup_data.json

运行脚本(已自动绕过 Wrangler 长度限制写入 sqlite):

bash

python3 scripts/import_local_data.py
附导入脚本

py

#!/usr/bin/env python3
"""
UptimeFlare - 数据导入脚本
详细文档查看: scripts/import_data_guide.md
运行此脚本: python3 scripts/import_local_data.py
"""

import json
import subprocess
import sys
import os

def main():
    # 检查备份文件是否存在
    backup_file = "backup_data.json"
    if not os.path.exists(backup_file):
        print(f"❌ 错误: 找不到备份文件 '{backup_file}'")
        print("\n请先从生产环境导出数据:")
        print('  npx wrangler d1 execute <YOUR_DB_NAME> \\')
        print('    -c /dev/null \\')
        print('    --remote \\')
        print('    --command "SELECT value FROM uptimeflare WHERE key = \'state\'" \\')
        print('    --json > backup_data.json')
        sys.exit(1)

    # 读取备份数据
    print(f"📖 读取备份文件: {backup_file}")
    try:
        with open(backup_file, 'r', encoding='utf-8') as f:
            data = json.load(f)
    except json.JSONDecodeError as e:
        print(f"❌ 错误: JSON 格式错误 - {e}")
        sys.exit(1)
    except Exception as e:
        print(f"❌ 错误: 读取文件失败 - {e}")
        sys.exit(1)

    # 提取 state 数据
    if not data or len(data) == 0:
        print("❌ 错误: 备份文件为空")
        sys.exit(1)

    # Wrangler 导出的格式可能包含 results
    state_value = None
    if isinstance(data, list) and len(data) > 0:
        if 'results' in data[0] and data[0]['results']:
            state_value = data[0]['results'][0].get('value')
        else:
            state_value = data[0].get('value')
    elif isinstance(data, dict):
        if 'results' in data and data['results']:
            state_value = data['results'][0].get('value')
        else:
            state_value = data.get('value')
    else:
        print("❌ 错误: 无法识别的数据格式")
        sys.exit(1)

    if not state_value:
        print("❌ 错误: 找不到 'value' 字段")
        sys.exit(1)

    print(f"✅ 成功读取数据 ({len(state_value)} 字符)")

    # 转义 JSON 字符串中的特殊字符
    # 将单引号替换为两个单引号(SQLite 转义方式)
    # 将单引号替换为两个单引号(SQLite 转义方式)
    escaped_value = state_value.replace("'", "''")

    print("\n🔄 准备导入数据...")
    import glob
    db_files = glob.glob('.wrangler/state/v3/d1/miniflare-D1DatabaseObject/*.sqlite')
    if not db_files:
        print("❌ 错误: 找不到本地数据库,请先运行一次 npm run dev 初始化")
        sys.exit(1)

    latest_db = max(db_files, key=os.path.getmtime)
    print(f"🔄 绕过 Wrangler 限制,使用 sqlite3 直接写入数据库...")

    try:
        sql = f"INSERT OR REPLACE INTO uptimeflare (key, value) VALUES ('state', '{escaped_value}');"
        subprocess.run(['sqlite3', latest_db], input=sql, text=True, check=True)
        print("✅ 数据导入成功!")
        print("\n✨ 完成! 现在可以重启开发服务器:")
        print("  npm run dev")
    except Exception as e:
        print(f"❌ 错误: 导入失败 - {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()

步骤 3.4:重启开发服务器

bash

# 停止之前的服务器(Ctrl+C)
# 重新启动
npm run dev
# 现在应该可以正常访问了

生产部署 ​

1. 创建 Cloudflare API 令牌 ​

创建步骤如图示,注意第 5 步的时候,要添加对数据库 D1 的编辑权限,是这个默认模板里没有的,之后就是继续确定等操作了。

创建完成后记得复制 API,然后将该 API 绑定到你的 Github 仓库,key 名:CLOUDFLARE_API_TOKEN

2. 创建通知 API ​

https://resend.com/,注册并创建一个 API,API 复制备用。然后再创建一个 domain 来绑定你的 API。如果你的域名直接在 CloudFlare 上托管的话,直接会提示自动修改 CloudFlare 的 DNS 解析,如果是其他服务商的域名,需要你按他的要求去修改。

同 Cloudflare API 一样,这个 API 也去 GitHub 仓库添加并绑定,key 名:RESEND_API_KEY

3. 创建部署到 CloudFlare 的工作流 ​

在 GitHub 仓库的 Action 里,直接运行已有的工作流 .github/workflows/deploy.yml

4. 在 CloudFlare 里查看服务并检查 ​

运行正常的话,你的 Workers 和 Pages 里会多出两项服务,一个 uptimeflare page 和一个 uptimeflare_worker,数据库里会多出一个 uptimeflare_d1 数据库。

uptimeflare page里设置一下自定义域,即可访问你的状态监控服务

注意事项 ​

  1. D1 数据库限制

    • ✅ 免费版:每天 100,000 次读取
    • ⚠️ 单次查询最大 1MB
    • ⚠️ 写入有延迟(最终一致性)
  2. Worker 限制

    • ✅ CPU 时间:10ms (免费) / 50ms (付费)
    • ⚠️ 内存:128MB
    • ⚠️ 请求大小:100MB
  3. Next.js Edge Runtime

    • ⚠️ 不支持 Node.js API
    • ⚠️ 不支持某些 npm 包
    • ✅ 使用 runtime = 'experimental-edge'
  4. 本地数据库

    • ⚠️ D1 本地数据库与生产环境完全独立
    • ⚠️ 本地调试需要导入数据
    • ✅ 数据库文件位于 .wrangler/state/v3/d1/ 目录
    • ✅ 重置数据库:删除 .wrangler/state 目录后重新执行步骤3

参考资料 ​