
1. 监控这种中间件先想清楚要盯什么Mycat作为数据库分库分表中间件承担着应用和MySQL实例之间的SQL路由、读写分离、故障切换、结果集聚合等核心职责。生产环境里一旦Mycat出问题影响范围是整个业务链路不只是某一个库。所以围绕Mycat建立一套可落地的监控体系是每个用了Mycat的团队绕不开的运维任务。这个章节聊的是Mycat监控工具但不只是把几个开源监控界面截图列一遍。我打算从监控的分层模型讲起把我实际部署和排障过程中用到的工具、命令、踩过的坑一起整理出来。适合刚接手Mycat维护的DBA或后端开发已经在用Mycat的人也能从中找到一些排查思路的补充。先说结论监控Mycat核心要盯四层东西。基础层进程是否存活、端口是否在监听、Mycat主机的CPU和磁盘IO。JVM层堆内存使用、GC频率和停顿、线程状态。Mycat本身是Java应用JVM健康直接决定中间件稳定。数据源层每个datanode对应的后端MySQL连接池是否健康、读写分离的balance策略是否正常、主从切换后数据源状态是否恢复。业务层SQL执行的总量和耗时分布、慢SQL、大结果集、事务占用连接的时长。很多团队刚开始做Mycat监控时只在基础层打转进程挂了告警一下端口没了重启一下。但真正的生产事故往往先表现在数据源连接池被打满、慢SQL把CPU拖垮、GC频繁导致Full GC停顿这时候进程还活着端口还通着常规的进程存活监控一点忙都帮不上。所以这套监控方案重点放在数据源层和业务层配合JVM监控补充底层视角。后面讲到的每个工具、每条命令都是从这三个需求出发选出来的。2. 先搭基础监控玩懂自带命令再上工具2.1 命令行监控是第一道防线Mycat从早期的1.6版本到后续的新版本一直保留了通过MySQL协议访问的管理端口。默认管理端口是9066普通业务端口是8066。连上管理端口之后用show开头的命令族就能拿到Mycat最核心的运行时状态。这些命令是最原始但最有用的监控手段很多可视化界面里的数据底层也是靠这些命令采集的。连接方式很简单mysql -h127.0.0.1 -P9066 -u mycat -pmycat登录之后最常用的几条show命令我整理成了一张表。命令作用生产场景使用频率show version查看Mycat版本号排查版本差异高show database查看逻辑库列表中show datanode查看数据节点状态高show datasource查看后端数据源连接信息和状态非常高show connection查看当前前端连接和事务状态非常高show sql查看最近执行的SQL和响应时间高show sql.sum查看SQL执行统计汇总高show threadpool查看线程池使用情况中show backend查看后端连接详情高show cache查看缓存命中情况低实际上去到生产环境我通常先跑一遍show datasource和show connection。先说show datasource它返回的字段里最关键的几个是name数据源名称对应schema.xml里dataHost配置的name属性。host后端MySQL地址。port后端MySQL端口。W写权重。R读权重。idle空闲连接数。active活跃连接数。total总连接数。execute累计执行SQL次数。如果active长期接近total说明这个数据源的连接池压满了。这时候去查业务SQL基本能定位到是慢查询还是连接泄漏。show connection能进一步看到每个前端连接正在执行什么语句、开启事务多久了。有一次排查线上偶发超时就是靠show connection发现一个连接长时间卡在SELECT上事务开启时间已经超过300秒由此顺藤摸瓜找到了一条没走索引的大表查询。2.2 JVM监控不能漏Mycat进程本身是Java应用OutOfMemory或者频繁Full GC会直接表现为SQL响应变慢、连接被重置甚至整个进程僵死。所以JVM层面的监控要单独拿出来讲。最简单的做法用JDK自带的jstat和jmap就能满足日常巡检。# 查看GC情况每1秒输出一次共输出10次 jstat -gcutil mycat_pid 1000 10 # 查看堆内存分代情况 jstat -gccapacity mycat_pid重点关注Full GC次数和Full GC耗时。如果Full GC频繁说明堆大小设置不合理或者存在内存泄漏。新生代频繁Minor GC一般是对象分配速率过高这时候要结合SQL分析看看是不是有大量临时表或大结果集产生。堆内存设置方面我的经验是不要盲目追求大堆。Mycat的瓶颈往往不在堆大小而在GC停顿。给Mycat分配8GB甚至更大堆导致一次Full GC要停顿数秒这期间所有SQL都会被阻塞业务侧表现就是瞬间超时雪崩。生产环境Mycat的堆内存建议控制在4GB到6GB之间配合G1垃圾回收器把停顿控制在可接受范围。具体参数可以在Mycat的启动脚本里调整JAVA_OPTS-Xms4G -Xmx4G -XX:UseG1GC -XX:MaxGCPauseMillis200另外dubbo的线程池状态也要盯。Mycat内部有独立的线程池处理前端请求和后端IO。当并发连接数超过线程池处理能力时新请求会进入等待队列。用show threadpool可以看到当前活跃线程和队列长度。队列持续积压说明线程池大小不够光靠重启解决不了问题要改配置。2.3 基础监控的快速落地方式如果团队还没有统一的监控平台先用一个几十行的小脚本把Mycat的核心指标拉起来比什么都强。我在应急阶段写过类似的脚本思路是定期执行show datasource、show connection、show threadpool把关键字段解析后拼成监控数据发给内部监控系统或者直接写进日志文件供排查使用。核心伪代码逻辑#!/bin/bash # 每分钟执行一次将Mycat关键指标采集到本地文件 while true do mysql -h127.0.0.1 -P9066 -umycat -pmycat -e show datasource /data/mycat_monitor/datasource.log mysql -h127.0.0.1 -P9066 -umycat -pmycat -e show threadpool /data/mycat_monitor/threadpool.log sleep 60 done这个脚本看起来简单但真出问题时非常有用。有一次排查一个周期性出现的慢查询就是翻历史日志发现某段时间active连接数出现阶梯式上涨推算出了连接池打满的时间窗口配合应用日志精准定位了问题SQL。工具再复杂数据积累的底层逻辑是一样的。3. 端到端可视化监控Mycat-web部署实录3.1 为什么还需要一个可视化平台命令行监控虽然能拿到全部数据但有两个痛点解决不了一是历史数据无法直观对比二是告警机制需要自己搭。Mycat-web这个可视化工具就是针对这两个痛点设计的。Mycat-web本身是一个独立的Web应用部署后可以通过浏览器查看Mycat的各项实时指标、历史趋势图、SQL统计排行、数据源状态等。它还集成了Zookeeper注册功能支持集群环境下的多节点监控。虽然这个项目现在维护节奏一般但在很多公司的生产环境里依然在服役稳定性经得起考验。3.2 部署流程逐步拆解Mycat-web的部署依赖两部分Mycat-web应用本身以及Zookeeper用于配置存储和集群节点注册。没有Zookeeper也能跑但告警配置、节点信息同步等功能会受影响。所以我的建议是痛快点直接把Zookeeper一起部署。第一步部署Zookeeper。我用的是3.4.x版本解压后配置文件conf/zoo.cfg里主要设置三个参数。端口默认2181dataDir指定到一块独立磁盘路径避免系统盘空间写满影响系统稳定性。tickTime2000 dataDir/data/zookeeper clientPort2181第二步部署Mycat-web。下载压缩包后解压到指定目录修改配置文件mycat-web/WEB-INF/classes/mycat-web.propertieszookeeperlocalhost:2181 mycat_web_port8082这里有个容易忽视的点zookeeper参数填写的地址必须是Mycat-web能访问到的Zookeeper地址。如果Zookeeper部署在别的机器上这里要写那台机器的IP不能写localhost。第三步在Mycat-web的界面里注册Mycat节点。访问http://mycat-web_ip:8082/mycat/进入“Mycat配置”菜单填入Mycat的IP、管理端口9066和用户名密码。保存后Mycat-web会通过管理端口周期性拉取Mycat的监控数据。注册节点时如果发现界面提示连接失败先去目标机器上手动执行一次mysql -hmycat_ip -P9066 -umycat -pmycat -e show version如果这个命令都连不上说明Mycat的9066端口没有对Mycat-web服务器开放或者管理用户权限不对。走这个排查顺序基本能解决九成以上的连接问题。3.3 核心功能使用心得Mycat-web的界面上有几个板块实际生产中用得最多的是这么几个SQL统计分析。这个页面能看到按执行次数、耗时、返回行数排序的SQL列表。结合业务逻辑能快速判断哪些SQL需要优化。我见过一个案例某个统计报表接口固定查一张5000万行的大表返回行数超过10万导致Mycat到后端MySQL的网络传输长时间占用连接最终拖垮整个分片。通过这个页面定位到具体SQL后改成分页查询问题立刻缓解。数据源监控。这个页面展示每个dataHost下所有数据源的健康状态包括读写权重、连接数、心跳状态。主从切换后这里会实时反映新主库的写权重是否变为1从库的读权重是否正常。切换后我都会盯一会儿这个页面确认数据源状态稳定。物理机监控。Mycat-web还带了一个简单的物理机监控模块展示CPU、内存、磁盘IO等基础指标。虽然不如Prometheus那套精细但对于中小团队来说一个界面看完所有指标省事不少。3.4 集群多节点监控如果线上部署了多个Mycat节点通常是双节点互备或者一主一备Mycat-web支持把这些节点全部注册进来统一管理。每个节点独立展示状态切换查看非常方便。多节点模式下Zookeeper的作用就会凸显出来。所有节点的配置信息都注册到ZookeeperMycat-web从Zookeeper读取节点列表再逐一拉取监控数据。所以部署多节点时有个要求两个Mycat节点之间以及它们和Mycat-web之间网络要互通尤其是9066管理端口和2181 Zookeeper端口。这里分享一个实操经验多节点部署时建议把Mycat的server.xml、schema.xml、rule.xml这三份配置文件的版本保持一致。监控平台上如果发现两个节点的datanode数量不一致不要急着查监控脚本先对这三份文件做diff。在我的经验里大部分节点状态不一致的问题根因都是配置没同步而不是监控工具本身的问题。4. 监控数据接入告警体系别让可视化变成装饰品4.1 从“能看”到“能告警”Mycat-web本身带了一些告警功能比如数据源离线时在界面上变色提示。但真实生产环境里告警要能通知到人要能分级要能关联值班群光靠界面变色远远不够。所以我的做法是Mycat-web负责展示告警交给专业的监控系统来处理。思路很简单让监控系统定期去Mycat执行几条关键指标命令把结果和历史阈值做对比超过阈值就触发告警。这种方案听起来朴素但在实际运维中的准确率非常高而且不依赖Mycat-web的告警模块是否正常工作。我建议的告警指标和阈值如下。告警项采集命令建议阈值数据源不可用show datasource任意数据源心跳失败持续超过3次后端连接池耗尽show datasourceactive连接数超过total的80%持续5分钟前端连接数异常攀升show connection5分钟内连接数增长超过平时的50%SQL响应时间恶化show sql.sum平均响应时间超过1秒持续10分钟线程池积压show threadpool等待队列大小持续超过100JVM内存异常增长jstat堆内存使用率超过90%持续5分钟这套指标的采集可以通过脚本执行也可以接入到Prometheus体系里。如果团队有Prometheus推荐用mysqld_exporter的定制化配置或者自己写exporter把show命令的结果转成metrics。没有Prometheus的话用zabbix的自定义脚本采集也能达到同样的效果。4.2 告警去重和升级策略告警这块去重策略比阈值本身更容易被忽略。Mycat的数据源抖动可能由网络闪断触发一条告警每分钟发一次值班同事在群里看到满屏告警反而会把真正重要的告警忽略掉。我的经验是告警触发后先进入观察期比如同一个数据源连续3次心跳失败才正式告警。告警发送一次后进入静默期比如10分钟内不重复发送同类型告警。超过30分钟还持续处于异常状态则升级到二级告警到更高级别的负责人。另外要说一个反常识的点不要对所有指标都设置告警。JVM的Young GC次数、连接数短时波动这类指标设置了告警只会让人觉得监控系统在狼来了。把告警留给真正需要人工介入的事件监控系统才有公信力。5. 真实的踩坑记录与排查心得5.1 数据源连接池被打满但业务量看起来不高有一次线上排查业务方反馈某个分片表的分页接口随机超时。登录Mycat执行show datasource发现一个datanode的active连接数已经等于total而其他datanode的active只有个位数。这个现象很典型说明SQL路由把请求都集中到了某个分片上。进一步查看show sql定位到一个按用户ID查询的语句。问题是接口在某种场景下会传入一个不常见的用户ID按照分片规则这个用户ID被路由到了同一个分片。结果这个分片成了热点连接池被打满。最后通过调整分片规则把这类用户的数据重新分布问题解决。这个案例想说明一个道理监控工具只能帮你定位问题在哪个环节真正解决还是要回到路由规则、SQL优化这些根因上。5.2 Mycat-web界面显示数据源离线但业务正常Mycat-web界面显示某个数据源离线但实际业务读写正常后端MySQL也健康。排查后发现Mycat-web是通过管理端口执行的show datasource来获取状态的而管理端口和执行用户的心跳检测走的是不同通道。有时候Mycat的管理线程池较忙对Mycat-web的拉取请求响应慢导致Mycat-web认为数据源离线。这个问题的处理方式比较简单一是把Mycat-web拉取监控数据的间隔调大一点从默认的10秒调整到30秒二是确保管理端口有独立的资源配额避免和业务线程互相影响。遇到类似告警先别急着重启Mycat多观察几个周期同时手动执行一下show datasource看真实状态。5.3 SQL统计与真实业务的偏差Mycat的show sql统计的是SQL路由和执行的结果但统计维度和业务日志里的请求维度不完全一致。举个例子一条应用SQL经过Mycat路由后可能被拆分成了多条分片SQLMycat的统计里会记录分片后的SQL信息。所以分析Mycat的SQL统计时要结合应用日志对照不要直接拿Mycat的数据断言业务某接口执行了某条SQL多少次。5.4 心跳检测不能完全替代业务探测Mycat的心跳检测默认是后端执行select 1之类的基础语句。它能确认连接存在但无法确认业务表是否可读写。我遇到过一次情况后端MySQL实例磁盘满select 1正常返回但业务表写入失败Mycat的数据源状态依然是健康的。这种情况需要额外增加一条针对核心业务表的心跳SQL比如select count(*) from核心表来真实反映数据源可用性。6. 轻量级监控的另一条路线从日志里挖价值6.1 开慢SQL日志定期分析Mycat自身的日志文件里包含了所有经过中间件的SQL执行信息。生产环境建议把慢SQL日志打开慢查询阈值的设置要结合业务情况。我一般建议先把阈值调到500毫秒观察一段时间如果业务本身没有这么慢的SQL再降到200毫秒。日志位置一般在Mycat安装目录下的logs目录文件名为mycat.log。慢SQL日志的价值在于它记录的是真实经过路由后的SQL和分片执行耗时比后端MySQL的slow log多了一层路由信息。拿到一条慢SQL能同时看到它被路由到了哪些分片每个分片的执行时间是多少这从MySQL自身日志里是看不出来的。结合这两份日志做分析SQL优化的效率会高很多。6.2 监控系统之间的数据互补Mycat-web、命令行、日志三者的数据各有侧重。命令行适合实时定位问题Mycat-web适合看趋势和对比日志适合做深度的SQL性能分析。三套数据配合使用基本覆盖了日常运维的绝大部分场景。举个例子当业务反馈“整体都慢”的时候先看Mycat-web的数据源监控确认后端MySQL是否健康再看线程池页面确认中间件自身是否有性能瓶颈如果都没有异常去翻Mycat的慢SQL日志定位到底哪类SQL耗时变长最后结合后端MySQL的慢日志看看是SQL本身变坏了还是路由到了性能较差的实例上。6.3 一条不算题外的补充监控数据要留痕无论用哪种监控方案历史数据的持久化一定要做。Mycat-web本身自带历史数据存储但数据保留周期有限。我习惯用脚本定期把show datasource和show sql.sum的结果转存到文件按月归档。这些历史数据在某些场景下价值极高特别是做容量规划和性能对比的时候。新上业务的预估流量、硬件扩容的决策依据都可以从历史监控数据的趋势里找到参考。7. 总结一下我现在的监控习惯我在实际使用中日常巡检的固定动作是早高峰时段上Mycat-web看一眼数据源状态和SQL排行执行一次show threadpool确认线程池没有积压翻一下前一天的慢SQL日志。每周做一次数据源连接数的趋势对比每月出一份Mycat监控维度的简要分析。这套动作做完Mycat这个中间件的运行状况基本处于可控状态。最后再分享一个小技巧把常用监控命令组合成一个shell脚本放在Mycat服务器上比如mycat_status.sh一行命令输出当前所有核心指标。既方便日常排查也方便交接文档里写清楚“如何快速判断Mycat是否健康”。这事看起来不起眼但真到凌晨三点被叫起来处理问题的时候能少敲几十个命令少一点烦躁多一分从容。