Excalidraw 与 Thanos:用视觉语言解构云原生监控架构
在一次深夜的线上故障复盘会上,团队盯着屏幕里那张密密麻麻的监控架构图——标准矩形框、规整连线、层层嵌套的组件,没人能一口气讲清楚数据到底从哪来、往哪去。突然有人提议:“要不咱们把它画得像白板上随手涂鸦那样试试?”于是,一张手绘风格的架构图被投屏展示出来:歪歪扭扭的方框、略带抖动的箭头、像是用马克笔随手写下的标签……奇怪的是,所有人反而立刻看懂了整个流程。
这正是Excalidraw的魔力所在。它不是传统意义上“完美”的图表工具,而是一种更接近人类思维节奏的表达方式。当我们将这种视觉语言用于描绘像Thanos 这样复杂的长期存储监控体系时,技术沟通的效率边界被悄然拓宽。
想象一个典型的云原生环境:几十个 Kubernetes 集群分布在不同区域,每个集群运行着独立的 Prometheus 实例,采集着成千上万条时间序列指标。问题来了——如何统一查看过去三个月的 QPS 趋势?某个服务的历史异常能否追溯到半年前?Prometheus 默认只保留几周数据,本地磁盘容量成了硬伤;多实例之间也无法联动查询。这就是 Thanos 出现的意义:它不取代 Prometheus,而是为它装上“翅膀”,让监控能力飞出单机局限。
但 Thanos 的组件并不少。Sidecar、Store Gateway、Compactor、Querier……这些术语堆在一起,很容易让人迷失在抽象概念中。这时候,一张好的架构图就不再是锦上添花,而是理解系统的必要入口。
而 Excalidraw 的价值,恰恰在于它能把这套复杂系统“降维”成一张仿佛刚在会议室白板上画完的草图。你可以看到:
- 一个略微倾斜的矩形写着 “Prometheus + Sidecar”,旁边连出一条波浪线指向云端图标;
- 云图标下挂着两个分支,分别通向 “Store Gateway” 和 “Compactor”,线条粗细暗示了主路径与后台任务的区别;
- 最上方的 “Querier” 像屋顶一样覆盖全场,向下发出两条查询线,一条实线代表实时数据,一条虚线代表历史回溯;
- Grafana 图标画得像个仪表盘,连接着最终输出端。
这不是机器生成的标准流程图,但它比任何标准化图纸都更容易被记住。
Excalidraw 的核心技术其实很朴素:它本质上是一个运行在浏览器中的前端应用,用 TypeScript 编写,完全开源(excalidraw/excalidraw)。它的“手绘感”并非预设图像,而是通过算法对标准几何图形进行微扰动处理——比如画一条直线时,会加入轻微的随机抖动和笔触粗细变化,模拟真实纸笔书写的效果。这种“去完美化”设计,意外地降低了技术图表的心理门槛。
更重要的是,它支持真正的实时协作。多个工程师可以同时编辑同一张画布,每个人的光标位置和操作轨迹清晰可见。这对于远程评审架构方案尤其有用。你不需要等某人“改完再发一版”,而是直接在他修改的过程中提出意见:“这里是不是应该加个缓存层?”、“这条数据流会不会形成环路?”——讨论本身就变成了文档演进的过程。
// React 中集成 Excalidraw 的典型方式 import React, { useState } from "react"; import Excalidraw from "@excalidraw/excalidraw"; const App = () => { const [elements, setElements] = useState([]); return ( <div style={{ height: "100vh" }}> <Excalidraw onChange={(elements) => setElements(elements)} initialData={{ elements, appState: { viewBackgroundColor: "#fff" } }} isCollaborating={true} onPointerUpdate={(payload) => { console.log("协同编辑指针更新:", payload); }} /> </div> ); };这段代码看似简单,却足以支撑起企业级知识库的核心功能。onChange可以对接后端自动保存,initialData支持加载模板(比如预置的 Thanos 架构骨架),isCollaborating启用后配合自定义 WebSocket 服务即可实现多人在线协作。许多团队已经将 Excalidraw 深度集成进内部 Wiki 或 DevOps 平台,作为默认的架构图编辑器。
更进一步,结合 AI 插件后,甚至可以通过自然语言指令生成初步结构。例如输入“画一个 Thanos 架构图,包含三个 Prometheus 实例上传到 S3,由 Querier 统一查询”,系统就能自动生成基础布局,人工只需调整细节。这种“对话式建模”正在改变技术文档的创作范式。
回到 Thanos 本身。它的核心思想可以用一句话概括:把 Prometheus 的本地存储扩展成分布式的、可无限伸缩的对象存储体系,并提供统一查询视图。它没有重写 Prometheus,而是通过一组松耦合组件在其外围构建能力增强层。
其中最关键的几个角色是:
- Sidecar:紧贴 Prometheus 部署,监听其 WAL(Write-Ahead Log)日志,定期将数据块打包上传至对象存储(如 S3、MinIO)。即使 Prometheus 崩溃,只要数据已上传,就不会丢失。
- Store Gateway:作为“历史数据代理”,从对象存储中读取已归档的数据块,并暴露 Store API 接口供查询使用。
- Compactor:后台任务组件,负责对对象存储中的数据进行压缩、降采样(downsampling)和生命周期管理(TTL),显著降低长期存储成本。
- Querier:真正的“大脑”。接收用户查询请求(如 PromQL 表达式),同时向本地 Prometheus 和远程 Store Gateway 发起查询,合并结果后返回完整的时间序列。
下面是典型的 Kubernetes 部署片段,展示了 Sidecar 如何与 Prometheus 共存于同一个 Pod:
apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-thanos-sidecar spec: replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: containers: - name: prometheus image: prom/prometheus:v2.47.0 args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" - "--web.enable-lifecycle" volumeMounts: - name: config mountPath: /etc/prometheus - name: storage mountPath: /prometheus - name: thanos-sidecar image: thanosio/thanos:v0.31.0 args: - "sidecar" - "--http-address=0.0.0.0:10902" - "--grpc-address=0.0.0.0:10901" - "--prometheus.url=http://localhost:9090" - "--objstore.config-file=/etc/thanos-bucket.yaml" ports: - containerPort: 10902 name: http - containerPort: 10901 name: grpc volumeMounts: - name: bucket-config mountPath: /etc/thanos-bucket.yaml readOnly: true - name: storage mountPath: /prometheus volumes: - name: config configMap: name: prometheus-config - name: bucket-config secret: secretName: thanos-bucket - name: storage emptyDir: {}这个配置的关键在于thanos-sidecar容器通过--prometheus.url连接到同 Pod 内的 Prometheus 实例,并利用--objstore.config-file加载对象存储凭证(通常以 Secret 方式注入)。一旦部署完成,数据就会按设定周期(默认每 2 小时)上传至远端,形成冷备。
整个数据流动路径如下:
graph LR P[Prometheus] -->|WAL 日志| S(Sidecar) S -->|上传 Block| OS[(Object Storage)] OS --> SG[Store Gateway] OS --> C[Compactor] SG -->|提供历史数据| Q[Querier] P -->|提供实时数据| Q Q --> G[Grafana] C -->|压缩与降采样| OS这张 Mermaid 流程图可以直接嵌入 Excalidraw 的文本元素中,或作为注释补充在角落。值得注意的是,Querier 是无状态的,因此可以水平扩展;Store Gateway 和 Compactor 也可以根据数据规模做相应扩容。整个架构具备良好的弹性与容灾能力。
实际落地时,有几个关键设计点值得反复推敲:
- 对象存储选型:虽然推荐使用 S3 兼容方案(如 MinIO),但必须评估网络延迟对上传性能的影响。若跨地域传输频繁,建议采用分层上传策略,优先保证关键集群的数据同步。
- Compaction 策略:不宜过于激进。频繁压缩会消耗大量 I/O 资源,影响整体稳定性。一般建议每日执行一次基础压缩,每周进行一次降采样(如生成 5m/1h 聚合数据)。
- 安全性:对象存储访问密钥必须通过 Secret 管理,禁用公开访问权限。同时启用 HTTPS 传输加密和 SSE-S3 静态加密,防止敏感指标泄露。
- 自身监控:别忘了 Thanos 自身也需要被监控!应为其各组件开启 metrics 接口,并接入另一套独立的监控体系,避免“灯下黑”。
当我们在 Excalidraw 上绘制这张架构图时,真正发生改变的不仅是表现形式,更是知识传递的方式。一张精心设计的手绘图,能让新入职的工程师在十分钟内掌握系统全貌;能在故障排查时快速定位瓶颈环节;也能在跨部门汇报中赢得非技术人员的理解与支持。
更重要的是,它鼓励了一种“低压力”的协作文化——没有人会觉得自己的草图“不够专业”,也没有人因为修改意见而感到冒犯。每一次拖拽、每一次重命名、每一次连线调整,都是集体智慧的沉淀。
如今,越来越多的技术团队开始意识到:最好的架构文档,往往诞生于一次轻松的头脑风暴之后,而不是一份冰冷的 PPT。Excalidraw 提供了这样的起点,而 Thanos 则代表了我们需要表达的复杂现实。两者的结合,不只是工具与系统的搭配,更是一种思维方式的契合:用最自然的方式,讲述最复杂的故事。
未来或许会有更多 AI 自动生成图表的能力融入其中,但无论如何演进,那个“看起来像是人亲手画出来的”特质,始终是最宝贵的——因为它提醒我们,技术终究是为人服务的。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考