MySQL 要远程盯着看这事儿听起来常规真正落地时全是细节。数据库不会只待在办公室旁边它可能跑在公司内网、家里机房或者云上的隔离网段你人也总有不坐在电脑前的时刻。到了外面想确认连接数是不是快满了、慢查询有没有突然暴涨、主从延迟还正不正常总不能每次都用手机爬回内网再去查。我这次把整套链路从头到尾过了一遍mysql_exporter 负责把 MySQL 的运行状态抽出来Prometheus 存储、Grafana 出看板最后用 cpolar 做内网穿透让公网设备能直接打开监控面板。实测下来页面加载很顺拖时间轴、刷图表基本不掉链子。这篇就把选型思路、部署步骤、隧道配置和踩坑记录完整写出来适合正在做 MySQL 运维、又希望在外网随时掌握实例状态的人直接参考。1. 这个需求是怎么冒出来的远程盯 MySQL 到底难在哪1.1 本地监控是常态远程才是真痛点先说说我为什么会被这个问题卡住。MySQL 实例平时待在机房里你在办公室的局域网内想连就连SSH 上去跑几条命令、开个本地监控面板一点问题没有。但人一旦离开内网环境——出差、回家、去客户现场——事情就变了。最常见的状态是“等业务先报障然后运维再上去查”。数据库响应变慢、连接数满了、主从延迟拉高往往是前端先炸了运营人员跑来反馈你才打开监控看看发生了什么。这种模式说白了是被动救火不是在监控。所以真正靠谱的思路是主动监控把连接数、QPS、慢查询、锁等待、主从复制延迟这类关键指标持续采集下来画成曲线再设定阈值。数据库还没出事曲线就已经开始示警了。问题在于大部分监控方案默认只在局域网内展示内网里看板很正常离开内网就两眼一抹黑。你可以高高兴兴地在办公室打开 Grafana但出差在外连不上那这套监控的“远程”价值就消失了。远程监控的痛点本质上有两件事一是要有稳定、低侵入的指标采集端二是要有一条安全可靠的通路让公网设备能访问到内网里的监控面板。前者我用 mysql_exporter 解决后者用 cpolar 这类内网穿透工具解决。两个合起来才算真正把远程监控打通。1.2 方案选型对比为什么是 mysql_exporter cpolar 这条链路在定下这套组合之前我其实把市面上常见的几种远程访问方式都梳理了一遍也实际踩过一些坑。这里直接列个对比表省得大家再走弯路方案优点真正的痛点公网直连 3306配置最简单远程工具填 IP 就能连数据库直接暴露公网暴力破解、漏洞扫描随时可能找上门风险极高SSH 隧道转发加密链路安全性不错需要一台带公网 IP 的跳板机多实例管理麻烦非技术同事基本不会用自建 frp 服务端完全自控能力上限高要自己买公网服务器、维护服务端成本稳定性都得自己兜着cpolar 内网穿透不需要公网服务器几分钟建好隧道只暴露指定端口免费隧道地址不固定需要自己补上访问鉴权我最终选 mysql_exporter Prometheus Grafana cpolar核心原因是它的“暴露面”最小。mysql_exporter 只通过 MySQL 的监控协议去读取状态数据库本身的 3306 端口完全不用暴露到公网cpolar 只转发 Grafana 面板所在端口公网用户能看到的只是一个登录页和图表。也就是说潜在攻击者就算扫描到了隧道地址他面对的也只是 Grafana 的登录框连接不到数据库本身。这套组合还有一个好处是分层清晰每一层都能独立替换。采集端不合适可以换 exporter存储太重可以换时序库面板不顺手可以换可视化工具内网穿透工具也不绑定死。对于个人项目和中小团队来说这种松耦合结构是最省心的。2. mysql_exporter 部署先把数据库的“体检数据”抽出来2.1 给 MySQL 建一个“只读体检账号”mysql_exporter 本质上是替 Prometheus 定期询问 MySQL“你现在状态怎么样”为了让这个“询问者”不乱动任何业务数据第一步就是建一个权限最小的只读账号。我习惯命名为 exporter密码用独立强密码绝不和业务账号混用也不放进代码仓库。在 MySQL 里执行CREATE USER exporterlocalhost IDENTIFIED BY 这里填强密码; GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO exporterlocalhost; ALTER USER exporterlocalhost WITH MAX_USER_CONNECTIONS 3; FLUSH PRIVILEGES;逐个解释这三个权限的用途SELECT允许读取information_schema和performance_schema中的性能表这是 exporter 取监控数据的主要来源。PROCESS允许查看线程状态对应SHOW PROCESSLIST有了它才能看到长事务和锁等待。REPLICATION CLIENT允许查询主从复制状态比如SHOW SLAVE STATUS主从延迟监控靠的就是这个权限。WITH MAX_USER_CONNECTIONS 3是我强烈建议加的。监控账号理论上并发连接数很少限制它最多同时建立 3 个连接可以防止 exporter 异常重试时把 MySQL 的连接池占掉。身边真有人踩过这个坑监控脚本没写超时时间半夜重试上百次直接把 MySQL 打挂了。如果 MySQL 和 exporter 不在同一台机器localhost要改成 exporter 所在机器的内网 IP或者用exporter192.168.1.%这种网段写法。不过安全起见exporter 最好就部署在数据库同机或同内网没必要为了“省一台机器”去跨网段访问。2.2 安装并启动 mysqld_exporterexporter 的二进制在官方仓库直接能拿到按 Linux 架构选对应版本下载解压到/opt/mysqld_exporter就行。我这边的习惯是不用包管理器装版本可控升级方便。连接信息不建议用DATA_SOURCE_NAME环境变量直接传因为进程列表里一眼就能看到密码。更稳妥的做法是把连接信息写进配置文件文件权限设置为仅 root 可读[client] userexporter password这里填强密码 host127.0.0.1 port3306把文件放到/etc/mysql_exporter/.my.cnf然后启动chmod 600 /etc/mysql_exporter/.my.cnf ./mysqld_exporter --config.my-cnf/etc/mysql_exporter/.my.cnf --web.listen-address0.0.0.0:9104这里有个问题值得解释exporter 监听地址为什么要用0.0.0.0:9104而不是127.0.0.1:9104如果 Prometheus 和 exporter 在同一台机器上用127.0.0.1更安全但如果 Prometheus 部署在另一台机器就必须监听在机器网卡能访问到的地址上。我通常把 Prometheus 也放在同一台服务器里用0.0.0.0只是图方便反正这台机器本身不对外暴露端口没额外增加风险。启动后先验证一下curl -s http://127.0.0.1:9104/metrics | grep mysql_global_status_threads_connected能输出一行类似mysql_global_status_threads_connected 15的内容说明采集通路已经打通。为了让重启不麻烦我建议写成 systemd 服务Restarton-failure和KeepAlive都配上。监控端不该掉线谁都不想因为 exporter 挂了而“盲监”。2.3 哪些指标值得重点盯exporter 输出的指标有成百上千个但日常运维不需要全盯盯多了反而眼花。我结合自己的使用习惯整理了一份核心指标清单指标含义为什么值得关注mysql_global_status_threads_connected当前连接数一旦接近max_connections新连接就会被拒绝mysql_global_status_queries累计查询数配合时间差可以算出 QPSmysql_global_status_slow_queries慢查询累计次数曲线突然上跳说明有 SQL 或锁在拖后腿mysql_global_status_uptime实例运行秒数突然归零说明 MySQL 重启过要追查原因mysql_slave_status_seconds_behind_master主从延迟秒数从库落后面太大读流量会读到过期数据有个容易忽略的点exporter 默认采集已经覆盖了这些核心指标不用额外手动执行SHOW命令。后面 Prometheus 的抓取频率配置好就行不需要在系统里再挂 crontab 去 curl 指标那是重复劳动。3. Prometheus Grafana让指标变成能看的看板3.1 Prometheus 拉取配置Prometheus 在这里扮演的角色是“定时问 exporter 要数据然后把数据存成时间序列”。核心配置在prometheus.yml加一个 jobscrape_configs: - job_name: mysql scrape_interval: 15s static_configs: - targets: - 127.0.0.1:9104 labels: instance: db-server-01如果有多台 MySQL就把 targets 列出多个再用instance标签区分实例。关于scrape_interval我实测下来 15 秒已经足够捕捉绝大多数问题。没必要图省事改成 5 秒甚至 1 秒因为每次抓取都会让 exporter 查一堆状态表频率太密对数据库有额外开销而数据库的监控指标也没有那么多秒级瞬变需要盯着。要知道监控看的是趋势和异常拐点不是每秒钟的精确值。Prometheus 启动后在http://127.0.0.1:9090/targets页面能看到这个 job 的状态。状态为UP且scrape duration稳定说明指标采集链路已经通了。3.2 Grafana 看板导入与常用面板Grafana 的价值是把机器可读的指标变成一眼能看懂的图。装好之后先加数据源地址填http://127.0.0.1:9090类型选 Prometheus。这一步没什么坑只要保证网络能通。然后导入现成的 MySQL 看板模板。社区有不少高质量的 MySQL Overview 模板基本都是基于 mysqld_exporter 的指标命名规则写的导入之后几乎不用改。我在 Grafana 模板库里搜 “MySQL Overview”挑了一个下载量高的导入。导入步骤很简单登录 Grafana进 Dashboards - Import输入模板 IDLoad 之后选好数据源确认导入就行。不过我的建议是不要贪多。模板里通常会有连接数、QPS、慢查询、缓冲池命中率、主从复制状态等一堆面板。远程访问场景下面板越多加载越慢反而干扰判断。我通常只保留三块核心区域连接与线程、查询性能、复制状态。面板越精简远程打开越快也越容易一眼发现异常。3.3 远程场景下看板怎么读到了远程场景看板的价值才真正体现出来。在外网打开 Grafana 之后我一般是按这个顺序扫先看连接数曲线长期在高位比如超过max_connections的 70%说明连接池要满了要考虑调大参数或优化应用连接释放。再看 QPS 曲线突然翻倍要么是业务高峰要么是有人在跑大查询或者全表扫描。然后看慢查询如果慢查询数和 QPS 同步上升基本可以判定是 SQL 性能问题需要抓慢日志分析。最后看一眼主从延迟数值持续增大而不是归零需要检查从库磁盘状态或复制线程是否中断。这里我特别想强调告警的作用。Prometheus 的 Alertmanager 或 Grafana 内置告警都行把连接数超过阈值、延迟超过 30 秒之类的事件推到钉钉或企业微信。配置不复杂但收益非常直接数据库开始“不舒服”的瞬间你手机上就能收到提醒而不是等业务喊你时才去打开面板。监控的真正价值恰恰是给你留出这段提前量。4. cpolar 内网穿透接入把内网看板“带到”公网4.1 cpolar 的工作原理先讲清楚 cpolar 这类内网穿透工具到底干了什么。正常情况下公网设备无法直接访问内网地址因为内网 IP 不在公网路由表里。cpolar 的做法是让本机运行一个客户端客户端主动向外部的云端节点发起一条长连接云端节点拿到连接后分配一个公网地址。公网用户访问这个地址时请求会被云端节点通过长连接隧道转发到本地指定端口。这个方向很重要因为是客户端主动连出去所以它不要求你家里或公司宽带具备公网 IP。你不需要去运营商那里要公网地址也不需要折腾路由器端口映射。打个比方内网里的 Grafana 就像一栋没有临街入口的屋子里的人cpolar 客户端是他在窗口摆的一部对讲机云端节点是楼下的前台。外来的访客按下前台对应的频道前台通过对讲机喊话屋里的人应答并回应整个过程不需要这栋楼真的开一扇临街大门。这个设计对监控场景特别友好3306 完全不用碰公网隧道只指向 3000 端口。数据库本身对外不可见你在公网能访问到的仅仅是一个经过登录认证的 Grafana 页面威胁面一下小了很多。4.2 安装与创建隧道安装 cpolar 客户端后先在官网注册账号拿到认证令牌并绑定到客户端。绑定完成后创建隧道就只是几分钟的事。我常用的方式是用命令行cpolar authtoken 你的认证令牌 cpolar http 3000http 3000的意思是建一条 HTTP 隧道把公网流量转发到本机 3000 端口也就是 Grafana 的默认监听端口。命令行跑起来之后会返回一个公网地址类似https://xxxx.cpolar.top在浏览器打开就是 Grafana 登录页。如果你更习惯图形界面cpolar 的管理后台也可以建隧道名称随意协议选 http本地地址填127.0.0.1端口填3000保存后会自动生成公网地址。这里有一个建议如果希望访问地址固定下来最好在 cpolar 后台开通固定二级域名并绑定到这条隧道。监控场景下这是刚需。免费随机地址每次重启都会变你总不能每次想看数据库状态都先翻一遍客户端日志找新地址。固定域名绑定后隧道基本是稳定的日常用起来和访问一个普通网站没有区别。4.3 为什么这样搭不容易卡很多朋友一听到内网穿透第一反应是“外面访问肯定卡”。实测下来在监控面板这个场景里影响远没有想象中那么大。原因是 Grafana 拉取的数据本身就很轻量面板页面、若干 JSON、一些小图标单次图表查询通常只有几十到几百 KB不是视频流也不是大文件下载对带宽要求很低。再加上 Grafana 对 Prometheus 的查询结果有缓存时间范围不变时重复查询会直接命中缓存图表加载是异步的首屏出现之后其他面板慢慢补观感就是“随点随开”。真正让面板变慢的往往是手机信号本身差或者首次加载时把所有不常用的面板全部拉了一遍。后面第 5 章会专门说怎么把这些多余请求压掉。5. 安全加固与调优远程监控不能只看“通不通”5.1 三层防护数据库、监控链路、公网入口远程监控最忌讳的心态就是“能通就行”。我把这条链路拆成了三层每一层都做了限制缺一层我都觉得不踏实。第一层MySQL 账号层。exporter 账号只有 SELECT、PROCESS、REPLICATION CLIENT 三个权限还限制了最大连接数。它无法修改任何数据无法执行 DDL更不可能删除任何表。就算攻击者拿到这个账号的密码他能看到的也只有性能相关的视图破坏力极其有限。第二层网络路径层。3306 端口只监听内网公网无法直连数据库。exporter 的 9104 端口也只在内网被 Prometheus 抓取。公网唯一能触达的是 cpolar 隧道指向的 3000 端口也就是 Grafana。第三层应用与隧道层。Grafana 有登录认证不能保持默认的 admin/admincpolar 隧道也建议开启访问鉴权在入口再挡一道账号密码。就算公网地址被人扫到对方面对的也只是一个登录页没有凭证什么都做不了。三层各管一段任何一层被突破攻击者都拿不到完整的数据库权限。这就是纵深防御的朴素形态。5.2 防爆破与访问控制公网地址一旦公布出去被扫描只是时间问题。Grafana 默认页面有清晰的登录框恶意请求一定回来试弱口令。在正式环境里我会做这几件事把 Grafana 的 admin 账号改名或至少把密码换成足够长的随机串创建独立的只读账号供日常查看面板使用在 cpolar 后台开启 Basic Auth 让隧道入口再挡一层关闭 Grafana 的匿名访问绝对不开启“匿名只看图”模式。有人可能觉得“一个监控面板谁会来搞我”。但你想想攻击者一旦进了 Grafana不仅能看你的连接数、QPS、主从状态还能看到数据源配置知道自己下一步可以探测哪些内网地址。信息暴露本身就是风险。多设一层认证成本很低不要把数据库的暴露风险寄托在“没人发现我”上面。5.3 开销控制与性能调优监控链路本身的开销其实很小。exporter 每次抓取相当于跑几次SHOW STATUS和查几张performance_schema表对 MySQL 的影响基本可以忽略。Prometheus 存时间序列占的是磁盘和内存实例少时完全不是负担。真正需要调优的是远程加载 Grafana 的体验。我实测有效的几个手段面板默认刷新间隔从“自动”改成 1 分钟或手动刷新避免多人同时挂着自动刷新页面白白占用查询资源。在 Grafana 里关掉不重要的大面板只保留核心几个。手机访问时直接打开具体 dashboard不要停在首页导航首页加载的小组件最多。cpolar 隧道尽可能选支持 HTTPS 的节点避免监控数据明文传输。多人同时使用合理分配查看权限不要所有人共用同一个管理员账号。这些操作做完后远程看板的体验基本就是“打开就出图、拖动时间范围稍微等一下而已”。配合第 4 章说的缓存机制“不卡壳”不是一句口号。6. 踩坑日志这些问题我替你先踩了6.1 问题一exporter 起来了指标却全是 0症状9104端口有响应mysql_up是 1但mysql_global_status_threads_connected这类指标全是 0。我第一反应是查 exporter 日志发现它在执行权限相关查询时反复报错。根源基本就是权限没给全。很多教程只让你给 SELECT忽略了 PROCESS 和 REPLICATION CLIENT结果 exporter 需要查线程状态和复制状态的时候权限不够查询失败后只能静默返回空值。处理方式很简单把 2.1 那三个权限完整授予一遍FLUSH PRIVILEGES重启 exporter。如果还不行用命令行手工验证账号能否正常执行SHOW GLOBAL STATUS和SHOW SLAVE STATUS。这一步原地排查很快就能定位。6.2 问题二隧道 online公网却 502cpolar 显示隧道在线公网打开却 502。这个问题的排查顺序很固定先本地确认服务是否活着再确认端口映射对不对。我在容器环境里踩过一次Grafana 跑在容器里端口映射成127.0.0.1:3000:3000cpolar 隧道指向本机 3000 端口看起来没问题。但问题在于 cpolar 客户端跑在另一个容器里它访问的127.0.0.1是它自己所在的容器并不是 Grafana 所在容器自然就 502 了。把端口映射改成0.0.0.0:3000:3000或者让 cpolar 客户端和 Grafana 跑在同一个容器网络里问题迎刃而解。6.3 问题三换了访问地址Grafana 图表全断远程面板能打开但图表区域一大片connection refused。查了一下是 Grafana 数据源里 Prometheus 地址写成了127.0.0.1:9090。这个地址在 Grafana 所在机器内访问没问题但图表请求是由浏览器直接发出的。浏览器在你的电脑上它拿到127.0.0.1自然找不到任何 Prometheus。解决办法是把数据源地址改成 Prometheus 所在机器的内网 IP比如http://192.168.1.10:9090或者在 Grafana 配置里用相对路径。改完之后重载一下页面图表就恢复了。这个坑很典型几乎每套远程化方案里都会遇到一次。6.4 问题四手机流量下看面板时快时慢同一块面板在 WiFi 下很流畅换成 4G/5G 就偶尔打不开。我观察下来问题通常不在隧道链路本身而在 Grafana 首次加载时拉取大量静态资源JS、CSS、字体文件。手机网络抖动时这些资源加载就会变慢。我的处理方式是给面板“减负”核心 dashboard 只保留少数图表调长 Grafana 的静态资源缓存在 cpolar 后台确认开启数据压缩。另外手机访问时尽量直接打开具体 dashboard不要每次都从首页导航进去。做了这些之后即便在信号一般的环境打开面板的耗时也在可接受范围内。最后再分享一点自己的体会。这套 mysql_exporter cpolar 的远程监控组合真正的价值不只是“在外面能看到面板”而是让你从被动救火变成主动发现。数据库指标曲线出现异常和业务真正报障之间通常隔着一段时间窗口这正是监控能给你的操作空间。安全底线一定别省最小权限账号、Grafana 强制登录、隧道访问认证三层防护缺一不可。跑一段时间之后你会发现你需要做的不是天天盯着面板发呆而是把告警配好然后该干嘛干嘛去。
阅读完成 · 觉得有帮助?