☰
基于cpolar与mysql_exporter实现MySQL远程监控:内网穿透+Prometheus实战
2026/10/21 23:28:51 网站建设 项目流程

1. 项目概述与核心思路

1.1 这个挑战到底在解决什么问题

先说说我为什么要做这个项目。手头有几台 MySQL 实例,平时跑着业务,但人不可能 24 小时蹲在机房盯着。最头疼的就是远程监控:数据库在内网里,人在外面,想看一眼慢查询、连接数、缓冲池命中率,总不能每次都用跳板机或者写一堆临时脚本吧。用 mysql_exporter 采集指标,Prometheus 负责存储和查询,这套组合本身非常成熟,问题是 Prometheus 的 Web 界面默认只监听本地端口,内网之外的设备根本访问不到。

cpolar 就是用来解决这个访问瓶颈的。它是一个内网穿透工具,可以把本地某个端口映射成一个公网可访问的临时或固定地址。也就是说,Prometheus 服务本身跑在内网机器上,通过 cpolar 把它的端口暴露出去,我在任何地方用浏览器打开那个公网地址,就能看到所有 MySQL 的实时监控数据。

1.2 为什么选择 mysql_exporter 加 cpolar 的组合

先聊聊为什么数据采集端选 mysql_exporter。Prometheus 生态里有很多 exporter,mysql_exporter 是最主流的一个,它在 GitHub 上长期维护,社区活跃,指标覆盖面很全。它通过标准的 MySQL 账号去执行 SHOW GLOBAL STATUS、SHOW VARIABLES 之类的查询,把状态变量转换成 Prometheus 指标格式。整个过程不需要在数据库里装任何插件,只要求账号有 PROCESS、SELECT 权限,对业务库零侵入。

再聊聊为什么隧道端选 cpolar。之前试过其他穿透方案,要么配置太复杂,要么免费版限速太严重,要么不稳定动不动就掉线。cpolar 的优势在于配置直观,一条命令就能起隧道,而且支持自定义域名、TLS 加密、访问认证,这对监控系统来说非常重要。监控数据本质上不算特别机密,但暴露在公网上总归需要做保护。

这个组合最适合什么场景?我总结了三个典型场景。

第一类是个人开发者或小团队,数据库在办公室或者家里的小服务器上,没有公网 IP,又想在出差时随时看一眼服务状态。第二类是客户现场的临时运维,有些项目部署在客户内网,监控系统搭好了,但人不可能常驻现场,远程排查问题需要一条安全通路。第三类是自己折腾 NAS、智能家居、个人网站的极客用户,已经有 MySQL 在跑,想搭一套轻量监控,又不想花大价钱买云主机。

如果你的需求正好落在这些场景里,这篇文章可以帮你省下半天的时间踩坑。

2. 环境准备与工具选型

2.1 需要提前准备哪些东西

开始动手之前,先把家底盘一下。我的实验环境是这样:一台 Ubuntu 22.04 的机器,跑着 MySQL 8.0,Prometheus 2.45 和 mysql_exporter 0.15 都已下载好。cpolar 用的最新版 3.x,支持 Linux 和 Windows,官方提供了安装脚本。

硬件要求不高,普通的 1 核 1G 小机器就能跑整套监控。数据量方面,这套方案面向的本来就不是那种每秒几万 QPS 的超大型数据库集群,而是中小型业务库,几十个连接、几百个活跃查询这种量级。如果你的 MySQL 是承载核心交易系统的,吞吐量巨大,那建议还是直接上云监控或者专业 APM 方案。mysql_exporter 加 Prometheus 更适合开发测试环境、内部管理系统、辅助业务的数据库。

网络方面有个前提需要确认:你的内网设备要能访问外网。cpolar 隧道本质上是从内网主动向外网建立长连接,所以只需要出网流量,不需要在路由器上做端口映射,也不需要公网 IP,这也是穿透方案相比传统 DDNS 加端口映射最大的优势。

2.2 mysql_exporter 的下载与安装

安装过程可以很简单,在 GitHub Releases 页面下载对应平台的压缩包,解压后里面就是一个可执行的二进制文件。下载之前先确认 CPU 架构,x86_64 的机器就选 amd64,ARM 的设备像树莓派就选 arm64。

解压完先别急着跑,先做一个基本的功能自测。我的习惯是直接在命令行前台运行一次,确认能正常输出指标再放到后台。

./mysqld_exporter --config.my-cnf=/etc/mysql_exporter/.my.cnf --web.listen-address=0.0.0.0:9104

这里有一个非常重要的细节:不要用明文密码写在命令行参数里。ps 命令会直接暴露所有进程的启动参数,密码等于公之于众。正确的做法是把账号信息放到配置文件里,然后给这个文件设一个只有 exporter 进程能读的权限。

配置文件 .my.cnf 的内容如下:

[client] user=exporter password=你的密码

这个账号需要在 MySQL 里创建,记得授权最小化。

CREATE USER 'exporter'@'localhost' IDENTIFIED BY '你的密码'; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';

三个权限缺一不可。PROCESS 用于获取线程状态,REPLICATION CLIENT 用于采集主从复制相关的指标,SELECT 是执行状态查询的基础权限。授权完了以后,最好用这个账号手动跑一条 SHOW GLOBAL STATUS 验证一下权限是否正确。权限一小,采集就会缺一堆指标,排查起来会平白无故多花时间。

2.3 Prometheus 的安装与数据源接入

Prometheus 同样在官网下载 tarball 解压就能用。配置文件的修改点只有一个,就是要告诉它去哪里拉取指标。打开 prometheus.yml,在 scrape_configs 里加一段 job:

scrape_configs: - job_name: mysql static_configs: - targets: ['localhost:9104'] honor_labels: true

honor_labels 这个参数容易被忽略。它决定当采集到的指标里自带 instance 标签时,要不要保留。默认的情况下,Prometheus 会强制覆盖 instance 标签为 targets 里的地址,这会导致后面在 Dashboard 上看到的实例地址不对。开了 honor_labels,就能保留 mysql_exporter 上报的原始实例标识,在多个实例共用一个 exporter 时尤其好用。

配置好之后,直接在浏览器打开 http://localhost:9090,输入一些基础查询语句,确认数据确实进来了。比如查 mysql_up 这个探活指标,返回 1 就代表 exporter 到数据库的通路是通的。

mysql_up{instance="localhost:9104"}

到这里,监控数据流已经在内网完整跑通了,接下来就是考虑让外部设备也能访问这套数据。

3. cpolar 隧道搭建与远程访问实操

3.1 安装 cpolar 并注册账号

cpolar 的安装非常直白,Linux 下用官方一行脚本,Windows 下下载安装包双击即可。

curl -L https://www.cpolar.cn/static/downloads/install-release-cpolar.sh | sudo bash

装完之后需要注册一个账号,然后在 cpolar 后台管理页面上找到自动生成的认证 token,执行下面的命令把本机客户端绑定到账号。

cpolar authtoken 你的token

登录支持的用途是管理隧道列表、绑定自定义域名、设置带宽和连接数限制。没有账号也可以起临时隧道,但地址是随机的,每次重启隧道地址就会变,远程监控不可能每次手动改地址,所以注册账号是必须的。免费套餐足够日常使用,有更高需求的话可以考虑付费版,但就监控 MySQL 这个场景,免费额度完全够用。

3.2 创建一条指向 Prometheus 端口的隧道

cpolar 的隧道有两种启动方式。第一种是临时隧道,直接在命令行指定协议和端口,适合快速验证。

cpolar http 9090

这个命令会输出一个公网地址,直接浏览器访问就能打开 Prometheus 的界面。适合本地开发、临时演示。缺点是地址是随机的,而且免费版的隧道域名后缀不固定,不方便长期记忆。

第二种是配置常驻隧道。先在 cpolar 的配置文件里定义一个隧道条目,绑定到本地的 9090 端口,后续可以给这个隧道绑定固定的二级域名。

配置文件路径一般在 /usr/local/etc/cpolar/cpolar.yml。

tunnels: prometheus: proto: http addr: 9090

保存后启动隧道,指定使用刚才定义的名字。

cpolar start prometheus

注意这里是 http 协议,不是 tcp。因为 Prometheus 自带的 Web 界面就是 HTTP 服务,cpolar 会自动做 HTTP 层转发。如果用的是 tcp,也能通,但就无法使用 cpolar 提供的 HTTP 层安全功能,比如访问密码保护。

3.3 绑定固定域名与访问认证配置

免费用户可以在 cpolar 管理后台的“预留”页面申请一个固定二级域名。绑定的好处很明显:监控工具的地址是固定的,你可以把它保存到浏览器书签,或者写到运维脚本里,不需要每次更换。固定域名加好之后,回到配置文件,在隧道定义里加一行:

tunnels: prometheus: proto: http addr: 9090 subdomain: mysqldash

这里的 subdomain 就是在后台预留时填写的固定子域名。改完配置需要重启隧道,然后访问 http://mysqldash.cpolar.cn,就能看到 Prometheus 的控制台了。

这里要特别提醒一下。Prometheus 的 Web 界面本身没有用户认证机制,谁拿到这个公网地址都能直接访问。监控数据里虽然不直接包含业务数据,但包含主机名、IP 地址、数据库版本这些环境信息,暴露在公网上还是有不小的风险。所以 cpolar 的访问认证一定要开。

cpolar 配置文件支持 basic_auth 的写法,需要提前在管理后台设置用户名和密码。

tunnels: prometheus: proto: http addr: 9090 subdomain: mysqldash basic_auth: - username: admin password: 设置一个高强度密码

重启隧道之后再次访问,浏览器会先弹出一个登录框,没输对用户名密码就直接返回 401。这一步的意义非常重大,等于在公网和你的 Prometheus 之间加了一道门禁。

3.4 用自定义域名完成访问闭环

如果你有自己的域名,cpolar 还支持把隧道绑定到自己的域名上。这个操作相当于在你的域名解析里加一条 CNAME 记录,指到 cpolar 的服务器,然后 cpolar 会自动申请 TLS 证书,以 HTTPS 的方式提供服务。

配置方式就是在隧道定义里使用 hostname 字段:

tunnels: prometheus: proto: http addr: 9090 hostname: monitor.yourdomain.com

用自定义域名的话,可以在域名解析层面加一层防护,比如只允许特定地区的 IP 访问,或者接入一层 CDN 做前置防护。当然,这会增加一些复杂度,对于大多数个人项目和小团队来说,直接用 cpolar 的固定域名加访问认证已经足够了。

4. 验证监控效果与常见问题排查

4.1 远程打开 Prometheus 验证数据采集

隧道配置完成之后,就该验证整个链路是不是真的通了。拿手机流量或者另外一台不在同一局域网的设备,打开浏览器输入刚才的固定域名,会看到登录框,输入账号密码进入 Prometheus 控制台。

在查询框里输入:

rate(mysql_global_status_questions[5m])

这个指标表示 MySQL 每秒处理的查询数,是判断数据库是否存活的常用依据。如果有曲线出来,说明整条链路全部正常:mysql_exporter 正常抓取数据、Prometheus 正常存储、cpolar 正常转发公网请求。

还可以看一下连接数:

mysql_global_status_threads_connected

正常情况下,业务没有大的波动时,这就是一条水平线。如果你远程看到这个数字突然大幅度上涨,就要注意是不是有连接泄漏了。这一招在排查故障时非常实用,以前必须坐在机房看的那张状态表,现在手机上就能实时看。

4.2 常见问题速查表

我在这个项目上前后折腾了几天,也踩了一些坑。整理成下面的表格,方便你对照排查。

现象可能原因解决办法
本地访问 9104 端口没有输出mysql_exporter 的配置文件权限过高或内容格式不对检查 .my.cnf 的权限,确保是 600;确认路径和 Prometheus 配置的路径一致
Prometheus 界面 mysql_up 为 0exporter 账号权限不足登录 MySQL 执行 GRANT 语句,确认 PROCESS、SELECT、REPLICATION CLIENT 三个权限都存在
远程访问 cpolar 域名提示 404隧道指向的端口写错了确认隧道配置里的 addr 是 Prometheus 的 9090,不是 exporter 的 9104
远程访问提示 401 但密码正确仍然进不去配置文件里 basic_auth 缩进格式不对YAML 对缩进非常敏感,确认 basic_auth 下面的列表项前面有对齐的空格
免费域名访问速度很慢带宽限制可以尝试把 Dashboard 的刷新时间调大,或者减少 Prometheus 的采集频率
隧道重启后地址变了没有使用固定域名在后台申请预留二级域名并绑定

4.3 踩过的坑和避坑技巧

第一个坑是 exporter 账号的 host 设置。上面给的授权语句用的是 localhost,但这个写法有一个隐患:如果 mysql_exporter 跑在别的机器上,通过 TCP 连接 MySQL,这个账号就会认证失败。正确做法是授权时限定为 exporter 所在机器的 IP,或者用百分号通配符,但要配上防火墙只允许指定 IP 访问数据库的端口。

第二个坑是配置文件权限。刚开始我把 .my.cnf 放在 /root 下面,直接 0644 权限,结果 mysql_exporter 跑起来后提示 insecure permissions。它不关心文件能不能用,它只在乎权限是不是太宽松。把权限改成 600,问题立刻消失。

第三个坑是采集频率和隧道流量的平衡。Prometheus 默认的采集间隔是 15 秒,一次抓取会拉取几千个指标,全部透明传输走 cpolar 隧道。免费套餐的带宽有限,如果监控的实例多,建议把采集频率降低到 30 秒,同时把 export 的某些高基数指标过滤掉。对绝大多数运维场景,30 秒的粒度和 10 秒的粒度在排查故障时没有察觉差异,但流量能省一半以上。

第四个坑是关于主从架构的监控。如果你的 MySQL 是主从复制模式,mysql_exporter 默认采集的是当前实例的状态,不会自动展示从库的复制延迟。想监控从库,需要额外配置参数,在启动命令里加上 collect.replica 相关选项,然后用专门的从库账号连接。这个细节我复习了好一阵子才搞定,官方文档写得不难找,但它藏在--collect.开头的长串参数里,不用心看很容易漏掉。

4.4 从简单监控到实用告警的扩展

隧道打通之后,想法就不应该只停留在看曲线图。Prometheus 本身就带了一个轻量级告警规则引擎,我现在给这套监控加了一个简单的告警配置:

groups: - name: mysql_alerts rules: - alert: MySQLDown expr: mysql_up == 0 for: 1m annotations: summary: "MySQL 实例挂了"

这个规则的意思是,如果 mysql_up 连续一分钟为 0,就触发告警。Prometheus 的 Alertmanager 可以把告警推送到各种渠道。个人使用的话,最省事的是接入 Telegram Bot 或者企业微信机器人,手机推到应用通知。这下整个闭环就真正完整了,人在外面,随时能知道数据库的健康状态。

5. 总结与个人体会

这个项目整体难度偏中等,对熟悉 Linux 基本操作的人来说,半天到一天就能全部配置好。mysql_exporter 负责数据采集,Prometheus 负责存储和计算,cpolar 负责打通远程访问的通路。三个组件各自专注一件事,配合起来非常顺滑,也方便后续单独升级或替换。

我在实际使用中最深刻的体会是,监控系统的价值不是看数据,而是在故障发生的那几分钟里,你不需要处在机房就能定位问题。以前数据库连着报警,我得连夜打车去机房,现在手机打开 Grafana 看一眼慢查询趋势就能判断是索引问题还是并发问题,远程就可以处理。

最后再分享一个小技巧:cpolar 隧道的日志默认输出到系统日志里,排查连接问题的时候,可以单独启动一个终端用调试模式看实时日志。

cpolar start prometheus --log stdout

这个模式下能看到每个 HTTP 请求的状态码和耗时。有一次远程访问异常,就是通过这个日志发现是客户现场的防火墙对中国大陆 IP 做了限制,换了个本地出口才解决。有些问题在线路层,有些问题在配置层,把日志逐步排查,总能找到原因。这套组合我已经稳定运行了半年多,没有操过心,你说值不值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询