
最近一直在折腾 Tongweb 的监控起因很简单现场环境里跑着一个监听 80909 端口的 Tongweb 实例业务方三天两头问「服务到底活着没有」「JVM 堆是不是又要爆了」光靠人工登录服务器看日志和进程效率太低也没法提前预警。后来我用 Prometheus普罗米修斯加 Grafana 把这事给办了——Prometheus 负责采集和存储 Tongweb 相关的指标Grafana 负责把指标画成看得懂的图表再配上报警规则服务一有异常苗头就能收到通知。这套方案我在多个环境里反复搭过中间踩了不少坑从端口不通到指标空白再到图表数据对不上几乎每个环节都有容易翻车的地方。这篇文章把我自己的实操过程完整梳理一遍从整体架构到具体配置再到常见问题的排查思路都写清楚。如果你也正打算监控 Tongweb或者已经在监控但总是差那么点火候这篇应该能帮你省不少时间。1. 整体设计与监控思路1.1 为什么要用 Prometheus 加 Grafana 监控 TongwebTongweb 本身是一款国产的企业级应用服务器中间件很多生产系统跑在它上面。它启动之后会监听一个业务端口比如标题里的 80909应用的所有 HTTP 请求都从这个口进来。但光知道端口活着还不够监控要解决的是更深层的问题JVM 内存是不是在持续上涨、活跃线程数是不是逼近上限、GC 频率是不是异常、请求处理耗时是不是突然变高。这些指标如果不提前收集等用户反馈「系统卡了」再去排查往往已经晚了。Prometheus 这个项目在云原生监控领域几乎成了事实标准它抓取指标的方式简单直接通过 HTTP 周期性拉取 exporter 暴露的数据存成自带时间序列的格式。Grafana 则负责把 Prometheus 里存的指标变成图表支持拖拽式仪表盘也能设置告警。这两个工具组合起来相当于搭了一个「采集 存储 可视化 告警」的完整闭环。选这套方案还有一个很实际的理由社区生态成熟。Prometheus 有大量的 exporter 可以复用Tongweb 又是 Java 系的应用服务器直接用 JMX exporter 就能把 JVM 和中间件内部状态暴露出来不需要在 Tongweb 里塞额外的 Agent侵入性很小。对于生产环境来说少改动、少重启本身就是最大的优点。1.2 监控架构与数据流向整条链路的组件划分是这样的Tongweb 进程内部通过 JMXJava Management Extensions暴露运行时数据JMX exporter 作为一个独立的小进程把 JMX 里的 MBean 属性转换成 Prometheus 认识的 metrics 格式然后在自己的 HTTP 端口上等着被抓取。Prometheus 根据配置文件里的 job 设置定期访问 JMX exporter 的 HTTP 接口把指标拉走存起来。最后 Grafana 连上 Prometheus用 PromQL 查询语句把指标画成面板。数据流向可以简单理解为「Tongweb → JMX exporter → Prometheus → Grafana」。这里要注意Tongweb 的 80909 是业务端口负责处理应用请求而监控数据的出口在 JMX exporter 那边走的是另一个端口。很多新手容易犯一个错误以为直接抓 80909 端口就能看到监控指标实际上你把浏览器打开http://服务器IP:80909/metrics看到的十有八九是应用页面或者 404而不是指标数据。我在设计时把 Prometheus 和 Grafana 放在一台独立的监控服务器上Tongweb 那边只部署 JMX exporter。这样监控采集和业务运行互相隔离即使监控服务器挂了也不会影响 Tongweb 对外服务。如果你的环境里机器紧张也可以把 Prometheus 和 Grafana 装在同一台但至少不要让它们和业务服务混部否则监控本身反而成了隐患。1.3 端口 80909 在监控任务里的角色标题里专门写了 80909说明这就是 Tongweb 实例的业务监听端口。在配置监控时我习惯先在服务器上用ss -lntp | grep 80909确认这个端口确实被 Tongweb 进程监听了这是后续所有监控动作的前提。实际上监控任务里关心的端口有两个一个是业务端口 80909它是我们要保护的对象所以监控的目标是「这个端口对应的服务是否健康」另一个是 JMX exporter 暴露指标的端口比如我习惯用 9101。这两个端口要分清在 Prometheus 抓取配置里填的是 9101不是 80909。有些版本 Tongweb 也支持开启自带的监控组件会额外监听一个管理端口具体端口号看安装目录下的配置。这个后面在采集配置章节我会专门讲。总之80909 是业务入口监控不直接碰它碰的是旁边那个 exporter。2. 环境准备与组件选型2.1 监控组件版本选择与关键考量先列一下我实际使用的组件版本和选择原因。组件版本建议选择理由Prometheus2.45 以上稳定版长时间序列存储成熟查询性能好配置简单Grafana10.x 长期支持版可视化能力强告警规则配置方便插件生态丰富JMX exporter0.19.0 或更新的版本官方维护支持 Java 8 及以上JMX 指标抓取稳定Tongweb7.x 及以上不同版本 JMX 配置方式略有差异但整体思路相同版本选择上我的建议是「不用追最新但别用太老」。Prometheus 的 2.x 系列接口基本稳定升级迁移成本不高Grafana 的 10.x 版本对告警和面板的体验都做得很好JMX exporter 尽量选官方 GitHub 仓库里的 release 版本不要用网上随便找的旧包否则可能出现 Java 版本不兼容的问题。还有一点很多人忽略Tongweb 是基于 Java 的应用服务器所以监控机的 Java 环境和目标机的 Java 环境都要提前确认。JMX exporter 是跑在目标机上的普通 Java 进程如果你的目标机没有装 JDK那 exporter 都起不来。我在现场遇到过目标机只有 JRE 的情况后面又补装了 JDK 才解决。2.2 Prometheus 安装与初始化Prometheus 的安装方式有二进制包、Docker 容器、包管理器等。我在生产环境里更偏好二进制包方式因为依托 systemd 管理开机自启和日志处理都方便。解压之后立即用配置启动可能有点太心急。因为 prometheus.yml 里默认会配置抓取 Prometheus 自身的指标所以第一次启动其实不用改动配置直接运行就能在自带的界面上看到监控自己的数据用这个来验证「Prometheus 有没有正常工作」是最快的办法。启动完成后Prometheus 默认监听在 9090 端口。浏览器打开http://监控服务器IP:9090可以在 Status → Targets 页面看到抓取目标列表。这时候只有一个prometheus的 job状态应该是 UP说明抓取链路正常。这个页面后面经常用到配置 Tongweb 抓取任务之后基本每个目标的状态都能在这里一眼看明白。2.3 Grafana 安装与初始化Grafana 的安装同样提供了多种方式。二进制包解压后运行./bin/grafana-server就能启动默认端口是 3000。第一次访问会要求设置管理员账号密码这里我的建议是设置一个强密码因为 Grafana 一旦暴露到公网弱密码是很危险的。初始化完成后第一件事不是急着配数据源而是先把 Grafana 的语言和时区调整好。虽然默认英文界面也能用但中文环境下图表里的时间显示不对会很影响判断。我习惯在 User Preferences 里把 Language 改为中文如果安装的语言包支持的话时区设置为 Asia/Shanghai。Grafana 本身不存储监控数据它只是一个展示层。所以配好 Grafana 之后下一步是去配置 Prometheus 数据源。在 Configuration → Data Sources 里选择 Prometheus填上 Prometheus 的访问地址比如http://127.0.0.1:9090保存之后点 Save Test如果显示绿色成功提示就说明 Grafana 和 Prometheus 的通道已经打通。3. Tongweb 指标采集配置3.1 Tongweb 的指标从哪里来Tongweb 作为 Java 中间件运行时状态基本都挂在 JMX MBean 上。JMX 是 Java 平台自带的管理扩展机制应用服务器会把线程、内存、类加载、连接数等关键信息注册成 MBean外部工具可以通过 JMX 协议远程读取这些属性。但 Prometheus 本身不认识 JMX它只认 HTTP 接口返回的文本格式指标。所以中间需要 JMX exporter 这个翻译官。JMX exporter 启动时配置一个 JSON 格式的规则文件里面写明要抓取哪些 MBean 的哪些属性以及怎么把这些属性里的值重命名成 Prometheus 指标名。它启动成功后一方面连接到本机的 Tongweb JMX 端口另一方面开放自己的 HTTP 端口给 Prometheus 拉数据。这里要多说一句Tongweb 的老版本和新版本在 JMX 配置上会有细微差别但从监控角度来说只要 JMX 远程端口能连上exporter 就能工作。我碰到的多数问题其实不是配置格式的问题而是 Tongweb 启动时压根没开 JMX 远程端口导致 exporter 连不上这个在第 6 章排查部分会重点讲。3.2 JMX Exporter 部署与规则文件配置JMX exporter 的部署分三步准备 JAR 包、准备配置文件、启动进程。第一步从 GitHub 仓库下载jmx_prometheus_javaagent-0.19.0.jar到 Tongweb 所在服务器的一个固定目录比如/opt/monitoring/。我习惯用 Java agent 模式而不是 standalone 模式。Java agent 模式是把 exporter 作为一个代理和 Tongweb 进程绑定在一起通过给 Tongweb 启动命令加-javaagent参数来生效这样 JMX 连接是走本机回环地址更安全。第二步编写规则文件tongweb.yaml。这个文件的核心作用是把 JMX 里的 MBean 属性映射成 Prometheus 指标。最简单粗暴的方式是用pattern正则匹配所有 MBean但那样导出的指标会非常多很多是无用的噪声。我一开始就是这么干的结果 Prometheus 里塞满了java.lang包下的各种底层计数器核心指标反而被淹没了。后面我把规则收敛了只留几类核心 MBeanrules: - pattern: java.langtypeOperatingSystemProcessCpuLoad name: tongweb_process_cpu_load - pattern: java.langtypeMemoryHeapMemoryUsageused name: tongweb_heap_memory_used - pattern: java.langtypeThreadingThreadCount name: tongweb_thread_count - pattern: CatalinatypeGlobalRequestProcessorrequestCount name: tongweb_request_count_total上面只是一部分示例。真实场景里你要先搞清楚 Tongweb 到底注册了哪些 MBean这个可以用 JDK 自带的jconsole工具连上 JMX 端口去看看到确定的 MBean 路径之后再写对应的 pattern 规则这样配出来最精准。第三步在 Tongweb 的启动脚本里加上 javaagent 参数。Tongweb 的启动脚本通常在安装目录的bin下比如startserver.sh或类似名称。找到 Java 进程启动那行在java命令参数里追加JAVA_OPTS-javaagent:/opt/monitoring/jmx_prometheus_javaagent-0.19.0.jar9101:/opt/monitoring/tongweb.yaml这个参数的意思是启动这个 Java 进程时加载 JMX prometheus agentexporter 监听 9101 端口规则文件用/opt/monitoring/tongweb.yaml。加完参数后重启 Tongweb。重启完成立刻检查 9101 端口有没有进入监听状态ss -lntp | grep 9101如果能看到监听再用浏览器或者 curl 访问http://127.0.0.1:9101/metrics应该能看到一堆以tongweb_和jvm_开头的指标。看到这些就说明 exporter 已经成功把 Tongweb 的运行时状态变成 Prometheus 的指标了。3.3 Tongweb 自带监控接口的使用有些版本 Tongweb 会自带监控模块可以通过 HTTP 接口暴露一些状态信息。这类接口的具体路径需要看版本对应的文档有的是/monitor有的是在管理控制台里。不过以我的经验自带的监控接口更多是给人看的格式不一定是 Prometheus 想要的 text 格式指标也不一定全直接用它来喂 Prometheus 有时候还得写额外的转换脚本反而麻烦。所以我在实际项目里始终以 JMX exporter 为主。只有在目标环境修改 Tongweb 启动参数受限、不允许动启动脚本的情况下才考虑用 standalone 模式的 JMX exporter 去连接远程 JMX 端口。但 standalone 模式多一层网络配置还要把 JMX 的 RMI 端口开出来风险更高能不用就不用。还有一个要点修改 Tongweb 启动参数之前先备份原脚本。我见过不止一次改完脚本漏了一个空格导致 Tongweb 起不来的情况备份了原脚本至少能快速恢复。这是运维的基本素养但关键时刻真的能救命。4. Prometheus 抓取配置与验证4.1 prometheus.yml 抓取任务配置Prometheus 的所有抓取任务都写在prometheus.yml文件里。为了让配置清晰我通常把自定义的抓取任务独立成单独的配置文件然后在主配置里使用rule_files和scrape_config_files引进来避免所有内容堆在一个文件里。针对 Tongweb 的抓取配置我写了一个独立配置文件tongweb.ymlscrape_configs: - job_name: tongweb-biz static_configs: - targets: [10.0.10.20:9101] labels: app: tongweb port: 80909 env: prod上面的 targets 填的是 Tongweb 所在服务器的 IP 和 JMX exporter 的端口 9101。labels 里的port: 80909是我额外加的一个标识标签目的是在图表里清楚地显示这个监控对象对应的是 80909 端的业务实例。这个标签只起说明作用不会影响实际的抓取逻辑。写完后在主配置文件prometheus.yml的末尾加上引用scrape_config_files: - /etc/prometheus/tongweb.yml然后重新加载 Prometheus 配置。Prometheus 支持热加载不需要重启进程命令是curl -X POST http://127.0.0.1:9090/-/reload也可以发送 SIGHUP 信号给 Prometheus 进程效果一样。热加载的好处是不中断监控生产环境推荐这种方式。4.2 验证抓取目标与指标查询配置加载之后马上到 Prometheus 的 Targets 页面看状态。正常情况下tongweb-biz这个 job 对应的 target 状态应该是 UP。如果显示 DOWN说明网络不通或者 exporter 进程有问题顺着链路查下去就行。Targets 状态确认正常之后再验证一下数据能不能查到。在 Prometheus 的 Graph 页面输入框里输入一个指标名比如tongweb_heap_memory_used点 Execute如果能看到时间序列数据说明整个采集链路已经完整跑通了。我习惯每一步都验证完再往下走不要一口气把所有东西配完再去查问题。这种增量式的验证方式看起来慢实际上是最快的因为每一步出了问题怀疑范围都很小一查一个准。Prometheus 的命令行工具promtool也可以用来检查配置格式promtool check config /etc/prometheus/prometheus.yml如果输出SUCCESS说明语法没问题。不过它能查的只是语法层面的错误目标地址通不通、exporter 返回的指标格式对不对它管不着最终还是要在 Targets 页面看状态。5. Grafana 可视化与告警配置5.1 添加 Prometheus 数据源Grafana 的可视化功能再强没有数据源也画不出东西。添加数据源的入口在 Configuration → Data Sources选择 Prometheus 类型在 URL 一栏填http://127.0.0.1:9090。这里有个细节Grafana 和 Prometheus 如果装在同一台机器上URL 直接填http://localhost:9090就行如果它们是两台机器URL 要填监控服务器的实际 IP而且要注意 Grafana 所在机器的防火墙要对 Prometheus 的 9090 端口放行。保存之后Grafana 会发一个测试请求到 Prometheus 的 API 接口。如果返回成功界面上会显示绿色提示如果失败最常见的原因就是网络不通或者 Prometheus 没启动。排查方法很简单在 Grafana 所在机器上执行curl http://127.0.0.1:9090/api/v1/status/healthy看返回结果就知道问题在哪一层。数据源配置成功之后我可以到 Explore 页面输入刚才在 Prometheus 里验证过的指标名比如tongweb_heap_memory_used点 Run queryGrafana 应该能拉出一张对应的时间序列图。5.2 构建 Tongweb 监控仪表盘仪表盘建设我建议从核心指标开始先画几块业务方最关心的面板再逐步补充细节。画面板的入口是 Dashboards → New Dashboard → Add visualization数据源选择刚才配好的 Prometheus然后设置查询表达式和图标样式。对于 Tongweb 监控我优先画的几个面板是JVM 堆内存使用量用tongweb_heap_memory_used绘制面积图能直观看到内存是否存在持续上涨趋势。活跃线程数用tongweb_thread_count绘制折线图线程数突然飙升往往是请求积压的信号。请求总次数和请求耗时分别用计数类指标和直方图类指标展示能看出请求量波动和响应时间。进程 CPU 负载用tongweb_process_cpu_load画折线图观察是否存在 CPU 长时间打满的情况。面板的查询表达式不一定只是简单选一个指标更多时候要配合 PromQL 函数。比如把内存值从字节转换成 MB可以这样写tongweb_heap_memory_used / 1024 / 1024再比如想画过去 5 分钟内请求数的速率可以这样写rate(tongweb_request_count_total[5m])这些表达式其实都是 Grafana 图形编辑器的 Query 栏里直接输入的 PromQL。写完之后把面板的标题改成中文比如「堆内存使用量MB」坐标轴单位设置成 MB图例名称设置成对应端口或实例名这样看仪表盘的人不需要费劲解读。面板数量和展示信息量之间要平衡。我一开始为了展示全面一口气拉了二十多块面板结果界面非常密看的人反而抓不住重点。后面精简成八块核心面板再把每块面板的单位、阈值、颜色都调清楚实用度反而更高。5.3 配置告警规则的基础思路告警是监控闭环里很重要的环节没有告警的监控只能算事后追溯。Grafana 的 Alerting 功能可以基于面板查询设置规则当指标超过阈值时立刻通过邮件、Webhook 等方式通知。我的告警规则一般从这些角度设计堆内存使用率超过 85% 持续 5 分钟、活跃线程数超过 200 持续 5 分钟、进程突然从 Prometheus 抓取目标里消失。阈值不是拍脑袋定的而是根据 Tongweb 实例的物理内存、业务类型和日常基线综合判断的。比如实例最大堆是 2GB日常使用率在 30% 到 50% 波动那阈值定在 85% 就比较合理留够了反应时间。提示告警规则刚配好时很多人容易收到一堆误报。原因是阈值定得太接近日常波动的最高点。可以先观察一个星期看看指标的日常分布再回过头调阈值。告警通知渠道方面如果公司有钉钉或者企业微信机器人可以用 Webhook 方式接入 Grafana。如果你的环境暂时没有这些邮件通知是最基础的选择。收到告警后第一件事是去 Prometheus 的 Graph 页面手动查询对应指标看趋势是持续走高还是偶发抖动判断到底要不要人工介入。6. 常见问题与排查技巧实录6.1 目标状态 DOWN端口连不上这是整套监控搭建过程中我遇到最多的一个问题。Targets 页面里tongweb-biz状态是 DOWN用telnet 目标IP 9101发现端口不通。排查思路先分清是哪一层的问题。在 Tongweb 所在服务器上执行ss -lntp | grep 9101如果这里能看到监听说明 exporter 进程是正常的问题出在网络上去查防火墙和云平台安全组规则。如果这里本身就看不到监听那问题就在 exporter 进程上去 Tongweb 的日志里看 javaagent 是否加载成功。我这边的实际案例是exporter 进程起了9101 端口也在监听但 Prometheus 那边还是 DOWN。后来发现是云平台安全组只放行了 80 和 443 端口9101 不在白名单里。把这些监控端口加进安全组之后状态立刻变成了 UP。所以遇到端口不通先别急着改配置把链路每一段的连通性测一遍再说。6.2 指标抓到了但全是空值还有一次target 状态已经是 UP 了但在 Graph 页面输入指标名却查不到数据或者查到了全是空值。这种情况通常是规则文件里的 MBean 路径和 Tongweb 实际注册的路径对不上。JMX 里的 MBean 路径变化很常见比如 Tongweb 版本升级某个对象的 ObjectName 从Catalina前缀变成了Tongweb前缀或者域名变了。我当时的做法是先用jconsole连上 Tongweb 的 JMX 端口把真实存在的 MBean ObjectName 逐条列出来再对照之前写的tongweb.yaml发现确实有个核心指标的前缀写错了导致 pattern 匹配不到任何数据。排查空值的快捷方式是直接访问 exporter 的输出curl http://127.0.0.1:9101/metrics | grep tongweb | head如果 curl 结果里能看到的指标名和你在 Prometheus 里查的不一致说明 exporter 和 Prometheus 之间有人改了指标名或者指令配置有差异。如果 curl 输出为空说明规则文件没有匹配到任何 MBean需要去改规则。6.3 重启与版本升级注意事项生产环境里 Tongweb 重启是最敏感的操作。修改启动脚本或者升级 JMX exporter 规则之后势必要重启 Tongweb这里一定要做好预案。我的建议是操作前先执行一次配置备份包括启动脚本、tongweb.yaml、prometheus.yml 和 Grafana 数据源配置。然后选择业务低峰期操作提前通知业务方会有短暂中断。重启完成后先确认 80909 端口恢复监听再确认 9101 端口有指标输出最后到 Prometheus Targets 页面确认状态为 UP整个流程才算闭环。升级 JMX exporter 版本时建议先在测试环境验证规则文件的兼容性。我之前从 0.15.0 升到 0.19.0 时就遇到旧的 pattern 语法在新版本里不再被支持导致一堆指标抓不到。升级前看一眼官方仓库的 CHANGELOG能省掉很多事。结语这套 Prometheus 加 Grafana 监控 Tongweb 的方案我在本地实验环境和生产环境都跑过整体稳定。最有价值的一点是它把中间件监控这个容易被人忽略的事情变成了一个低门槛、高回报的基础设施能力。实际操作中我的体会是监控的建设不是一锤子买卖它需要持续迭代。刚开始你画面板、定阈值看着很完整但用一段时间你就会发现真正关键的告警可能还没配全或者某些指标的含义理解得还不够透彻。所以我会定期回顾一下面板和告警规则把用不上的删掉把缺的补上。最后再分享一个小技巧把整个部署过程写成一份可复用的脚本和配置模板存在公司的运维仓库里。这样下次再遇到一个新增的 Tongweb 实例照着模板改改 IP 和端口就能快速上线监控省下的时间足够你多喝两杯咖啡了。