跳转到内容
use-cases / a-live-metrics-dashboard-no-backend / hero
PIPE · SSE · 无后端

没有指标后端的实时仪表盘

二十个 agent 用 curl -T 把指标推到一个管道 URL。你的仪表盘用 ?progress 读同一个 URL,把 SSE 流直接渲染进页面。无 InfluxDB、无 Prometheus、无抓取间隔。只是一根线。

阅读 Pipe 文档
use-cases / a-live-metrics-dashboard-no-backend / mechanism

一个 URL,两端

每个 agent 把它那一行 curl 进同一条管道路径。仪表盘的浏览器在那条路径上以 ?progress 打开一个 EventSource。Hoody Pipe 服务器什么都不存——一端到达的字节从另一端离开。

agent · monitor.sh
PUT · sender
#!/bin/sh
# Agent monitor loop — one line per second.
while true; do
  cpu=$(top -bn1 | awk '/Cpu/ [print $2]')
  mem=$(free | awk '/Mem:/ [printf "%.0f", $3/$2*100]')
  line="cpu=$cpu mem=$mem qps=$(cat /tmp/qps) ts=$(date +%s)"
  echo "$line" | curl -T - https://pipe.hoody.com/api/v1/pipe/metrics-$AGENT_ID
  sleep 1
done
线什么都不存
dashboard.html · 在你的浏览器里
GET ?progress · reader
// One <script> in one HTML file. No backend.
const tiles = document.querySelectorAll('[data-agent]');

tiles.forEach((tile) => [
  const id = tile.dataset.agent;
  // ?progress turns the pipe path into an SSE stream.
  const sse = new EventSource(
    `https://pipe.hoody.com/api/v1/pipe/metrics-$[id]?progress`,
  );

  sse.addEventListener('metric', (e) => [
    const [ cpu, mem, qps ] = JSON.parse(e.data);
    tile.querySelector('.cpu').textContent = `$[cpu]%`;
    tile.querySelector('.mem').textContent = `$[mem]%`;
    tile.querySelector('.qps').textContent = qps;
  ]);
]);

agent 在 curl。浏览器在 EventSource。管道在转发。两者之间没有任何东西要扩容、重启或买单。关掉仪表盘,流就结束。再打开它,一秒之内你又看到实时数据。

use-cases / a-live-metrics-dashboard-no-backend / powers

一块会蒸发的仪表盘的三种威力

你删掉后端所放弃的,会以更简单的形式还回来。

LATENCY

天然的亚秒级

没有抓取间隔要等。agent 最后一次写就是仪表盘当前这一帧。管道直接转发——没有中间刷盘。

OPERATIONS

无东西要保留,无东西要崩

无保留策略,因为无存储。无磁盘可填满、无压缩窗口、无时间序列索引可损坏。指标只在有人看的时候存在。

ECONOMICS

一份静态 HTML 文件就发版了

仪表盘是一份你能托管在任何地方——或从磁盘打开——的 HTML 文件。无 agent 要装、无守护进程要跑、无 DataDog 席位要开。管道 URL 就是整个堆栈。

use-cases / a-live-metrics-dashboard-no-backend / evaporates

蒸发了什么

标准的 agent 到仪表盘堆栈有四个活动部件。管道模型有零个。同一根线,半屏 curl。

BEFORE · 四个部件要看护典型堆栈
  • statsd / telegraf
  • InfluxDB / TimescaleDB
  • Grafana / Datadog
  • scrape 配置文件
四份配置 · 四次升级 · 四张账单
AFTER · 一根线两条 curl 命令
# 每个 agent:每个指标一行。echo "cpu=64 mem=42" | curl -T - https://pipe.hoody.com/api/v1/pipe/metrics-$ID# 每个查看者:一条 curl,或在 HTML 里 new EventSource()。curl -N https://pipe.hoody.com/api/v1/pipe/metrics-$ID?progress
无存储 · 无抓取器 · 无守护进程

当你跳过数据库时,那些你以前要管理的东西就不再存在。一根线上没有保留策略。

use-cases / a-live-metrics-dashboard-no-backend / capacity

管道给你什么

一条管道路径是一小块但真实的基础设施。数字来自 Hoody Pipe API 的保证,不是杜撰的基准。

  1. RECEIVERS PER PATH256

    最多 256 个仪表盘或 curl tail 可以用 ?n 订阅同一路径。最慢的读取者反压自己,但永远不阻塞其他人。

  2. PROGRESS SPECTATORS50

    每条路径最多 50 个 ?progress SSE 查看者。他们不占用接收者槽位——你的仪表盘标签页和你的终端可以并行观看。

  3. STORAGE LATENCY0 ms

    服务器不写磁盘。发送端到达的字节从读取端离开。两者之间没有刷盘窗口。

限制依据 Hoody Pipe API:接收者数量 1–256,每条路径 progress 旁观者上限 50,progress 连接 TTL 30 分钟,传输后驻留 30 秒。

use-cases / a-live-metrics-dashboard-no-backend / punchline

仪表盘没去查数据库。字节就那样到了。

周五 · 实时观看周六 · 蒸发
WHAT THE OLD ARCHITECTURE LOOKED LIKEagent → statsd → InfluxDB → Grafana四个活动部件 · 四份配置 · 四张账单
WHAT IT LOOKS LIKE NOWecho $line | curl -T - pipe/metrics一行——而且仪表盘只是一份 HTML 文件
阅读 SSE progress 规范
use-cases / a-live-metrics-dashboard-no-backend / replaces

它替代了什么

当你想要一块指标仪表盘时会去拿的标准工具。每一种都向你收一份数据库和一个守护进程的钱。管道两个都不收。

  • AWS Lambda + CloudWatch为只是 curl 的事按调用计费
  • 自建路由服务为了转发本来就有 URL 的字节,写整套微服务
  • Prometheus + Grafana 堆栈两个守护进程、一个抓取循环、一块自托管仪表盘
  • InfluxDB + Telegraf为屏幕之外不留的数据上一个时间序列数据库
  • DataDog 指标采集为只想看一次的数字按主机定价
  • 自建指标摄入流水线为 agent 直接 push 的值上 Kafka + 消费者 + sink
use-cases / a-live-metrics-dashboard-no-backend / cta

别再抓取。别再存储。看这根线——你不看的时候,线是空的。

阅读 Pipe 文档
use-cases / a-live-metrics-dashboard-no-backend / related

阅读其他内容