上次写了 Grafana + Prometheus 企业级监控部署流程,把 Node Exporter 的 CPU / 内存 / 磁盘都接进了 Grafana。文末提了一嘴 Media Unlock Monitor 做流媒体解锁监控,但那套方案实际用下来有几个痛点:

  • 它本质是挂在 systemd 里的检测脚本,指标格式和 Prometheus 语义贴合度一般,"解锁 / 限制 / 未解锁"全靠 Grafana 面板里的 value mapping 硬凑;

  • 多节点横向对比不方便,几十台落地机里哪台不解锁,要靠肉眼翻面板;

  • 升级、卸载、维护链路也比较粗糙。

所以这次我把整条链路重做了一遍,做了一个专门为 Prometheus 而生的解锁检测 exporter——media-exporter。本文是它的项目介绍 + 从零到一的部署教程,接着上一篇的 Prometheus / Grafana 环境直接往下走。

media-exporter 是什么

Media Exporter 是一个面向 Prometheus 的轻量级流媒体与 AI 服务区域可用性监测器。服务端用 Go 标准库实现,以 Linux 静态单文件发布,MIT License 开源,仓库在 github.com/kaze-kaze/media-exporter

它运行后会按你设置的周期(默认 30 分钟)从服务器出口直接检测 Netflix、Disney+、ChatGPT 等服务的区域解锁状态,并把结果暴露成 Prometheus 指标。Prometheus 每次抓取只读取上一轮已经完成的监测快照,不会因为抓取而触发新的外部请求——这一点和"抓一次测一次"的方案有本质区别,对服务商压力很小,也不会把采集弄成检测。

核心特点

  • Linux 静态单文件运行,无数据库、Node.js、Python、容器或运行时依赖;

  • 发布覆盖 amd64、arm64、armv7、armv6、386 五种架构;

  • 中英文交互式安装,自动识别 CPU 架构和服务器出口 IP 地区;

  • 自动地区、手动地区、AI 组合、全部监测四种模式;

  • 原生 Prometheus 指标,附带节点集群运维和单节点状态大屏两套 Grafana 仪表盘;

  • IPv4 / IPv6 / 单 IP / CIDR 白名单,默认仅允许本机访问;

  • systemd 安全加固(无额外 capabilities、系统目录只读),支持 OpenRC;

  • 发布包 SHA-256 校验,支持安全升级与卸载,不做无人值守自动更新。

范围

服务

全球

Netflix、Disney+、YouTube Premium、Prime Video、DAZN、Paramount+

北美

Hulu、Peacock、Philo、Sling TV、CBC Gem

欧洲

BBC iPlayer、ITVX、ZDF、Channel 4、France.tv、Canal+

日本

Abema、NHK+、TVer、DMM TV、FOD

韩国

TVING、Coupang Play、KBS Domestic

香港

MyTVSuper、ViuTV、HOY TV

台湾

Hami Video、Ofiii、KKTV、MyVideo、Friday Video

东南亚

meWATCH、Viu、Bilibili SEA

大洋洲

ABC iview、SBS on Demand、10 Play、9Now

AI

ChatGPT、Gemini、Claude

服务商的接口行为随时可能变化。当上游响应无法安全识别时,exporter 会返回 parse_errorunexpected,而不是猜测解锁结果。

部署教程

1. 一键安装

需要 root / sudo 权限、curl 或 wget、tar,并且能通过 HTTPS 访问 GitHub 的 Linux 服务器(systemd 或 OpenRC 均可):

bash <(curl -fsSL https://github.com/kaze-kaze/media-exporter/releases/latest/download/install.sh)

安装器会依次询问:语言、监测范围、分钟级频率、监听地址、运行端口、IP 白名单和安装目录。选择"允许所有 IP"时必须二次确认。

  • 自动模式:监测 Global 项目 + 服务器检测到的地区;

  • 手动选地区:同样会包含 Global 项目;

  • AI 模式:同时监测 Global、服务器地区和 AI 项目。

默认配置:监测频率 30 分钟、监听地址 0.0.0.0(所有 IPv4 网卡)、端口 9111、安装目录 /opt/media-exporter、白名单仅 127.0.0.1/32 和 ::1/128。

安装完成后,在服务器上直接验证:

curl -fsS http://127.0.0.1:9111/-/healthy
curl -fsS http://127.0.0.1:9111/metrics | head

首轮监测完成前 /-/ready 返回 HTTP 503 是正常现象。

2. 接入 Prometheus(书接上文)

和上一篇 Node Exporter 的接法完全一样,在 prometheus.ymlscrape_configs 里加一个 job:

  - job_name: media-exporter
    scrape_interval: 1m
    scrape_timeout: 10s
    static_configs:
      - targets: ["127.0.0.1:9111"]

抓取周期和监测周期相互独立:Prometheus 每 1 分钟读取一次缓存指标,exporter 自己按 interval_minutes 运行服务商探针。

promtool check config /etc/prometheus/prometheus.yml
sudo kill -HUP "$(pidof prometheus)"

重新加载后在 Prometheus 里查询:

up{job="media-exporter"}
media_exporter_ready{job="media-exporter"}

第一个应返回 1,第二个在首轮检测完成后变为 1。

多节点横向对比

几十台落地机的场景,给每台服务器加一个易读的 instance target label(注意不要加名为 region 的标签,它已被 exporter 指标占用):

  - job_name: media-exporter
    scrape_interval: 1m
    scrape_timeout: 10s
    static_configs:
      - targets: ["media-hk.example.com:9111"]
        labels:
          instance: hk-a
      - targets: ["media-us.example.com:9111"]
        labels:
          instance: us-b

远程采集时,exporter 的 listen 要绑定 Prometheus 能访问的地址,allowlist 和服务器防火墙都只放行 Prometheus 的实际来源 IP 或网段。Prometheus 在本机的话,直接绑定 127.0.0.1 最省心。

3. 导入 Grafana 仪表盘

仓库 dashboard/grafana/ 下有两套可直接导入的 JSON,中英文都有:

  • 节点集群运维(fleet-ops):多节点总览、趋势、横向比较、按分组拆分的服务矩阵、故障、出口信息和采集诊断;

  • 解锁状态大屏(status-wall):单节点大屏,动态显示当前有指标的服务分组。

导入方法:Grafana → Dashboard → New → Import → 上传 JSON → 选择 Prometheus 数据源,推荐 Grafana 11.3 或更新版本。可以直接用仓库的 raw 链接导入:

https://raw.githubusercontent.com/kaze-kaze/media-exporter/main/dashboard/grafana/media-exporter-fleet-ops-cn.json
https://raw.githubusercontent.com/kaze-kaze/media-exporter/main/dashboard/grafana/media-exporter-status-wall-cn.json

中文仪表盘有固定 UID,以后导入新版 JSON 并允许覆盖即可升级,不需要手动删面板。

4. 升级与卸载

升级继续使用同一个安装脚本,按语义版本(SemVer)比较:目标版本更高才升级,相同版本直接退出,较低版本拒绝降级。升级会保留 config.json,先校验新版本兼容现有配置再替换;如果服务启动或健康检查失败,会自动恢复上一版本。

bash <(curl -fsSL https://github.com/kaze-kaze/media-exporter/releases/latest/download/install.sh) upgrade

指定版本时使用完整的 GitHub Release 标签:

MEDIA_EXPORTER_VERSION=v1.2.3 bash <(curl -fsSL https://github.com/kaze-kaze/media-exporter/releases/latest/download/install.sh) upgrade

默认卸载删除服务和程序,但保留配置、配置备份和专用服务账号;需要彻底清理时用 uninstall --purge(会要求输入 PURGE 二次确认):

bash <(curl -fsSL https://github.com/kaze-kaze/media-exporter/releases/latest/download/install.sh) uninstall

5. PromQL 小抄

# 当前所有服务状态
media_exporter_probe_result{job="media-exporter"} == 1

# 探针技术故障(不影响服务可用性判断)
media_exporter_probe_result{job="media-exporter", state=~"timeout|network_error|parse_error|unexpected"} == 1

# 被服务商拒绝或不可用
media_exporter_probe_result{job="media-exporter", state=~"blocked|banned|rate_limited"} == 1

# 检测到的出口位置
media_exporter_ip_info{job="media-exporter"} == 1

项目信息

GitHub:kaze-kaze/media-exporter(MIT License,欢迎 star / issue / PR)

文档:README(中英)、Prometheus 接入指南、Grafana 仪表盘指南、服务端配置与运维说明,都在仓库 docs/ 目录。

致谢:项目参考了 RegionRestrictionCheckIP.Check.Place 和 ecs.sh 等公开工具可观察到的检测行为,均为独立实现,不作为运行依赖。

ps:个人经验——落地机集群里,10 台机器跑 exporter 对 1C / 1G 的小鸡毫无压力,真正的开销来自 Prometheus 侧,1 分钟抓一次绰绰有余。如果想要更完整的告警规则(服务失联、快照过期、探针故障),仓库的 Prometheus 接入指南里有一份保守的 starter 配置可以直接抄。

Media Exporter 与任何被监测服务商均无关联,请合理使用,遵守服务条款及适用法律。