RabbitMQ监控实战:Prometheus+Grafana搭建与告警规则详解
1. 为什么消息队列的监控值得单独拎出来讲做后端开发这些年我越来越觉得消息队列这东西有点像家里的水管系统——平时你根本不会注意到它一旦堵了或者爆了整个屋子都得遭殃。RabbitMQ 作为消息中间件里的老牌选手用起来确实顺手但很多团队在项目初期只关心“消息能不能发出去、能不能收到”等到线上出了状况才发现自己对这个系统的运行状态几乎一无所知。监控这件事说白了就是给你的消息队列装上仪表盘和报警器。你需要知道当前有多少消息在排队、消费者是不是在正常工作、连接数有没有异常飙升、内存和磁盘会不会突然告急。没有这些数据你就是在盲开一架飞机仪表盘全黑只能等坠毁了才知道出了问题。这篇文章主要面向已经用过 RabbitMQ、但还没系统做过监控的开发者或者正在为线上环境搭建可观测性体系的运维同学。我会从监控的核心指标讲起然后一步步拆解怎么用官方管理插件、Prometheus 以及告警规则把整个监控链路搭起来。中间会穿插我自己踩过的坑和一些参数调优的经验尽量让你少走弯路。2. 监控体系整体设计与核心指标拆解2.1 监控的四个层次在动手配置之前先想清楚我们要监控什么。我习惯把 RabbitMQ 的监控分成四个层次从外到内依次是基础设施层服务器本身的 CPU、内存、磁盘 I/O、网络带宽。这一层不归 RabbitMQ 管但它直接决定了 RabbitMQ 能不能稳定运行。节点层RabbitMQ 服务进程的状态包括 Erlang 虚拟机的内存占用、文件描述符数量、TCP 连接数等。队列层每个队列的消息堆积量、消费者数量、消息进出速率、未确认消息数。业务层从业务角度定义的健康指标比如订单消息的端到端延迟、死信队列的增长趋势。很多团队只做了第一层和第二层觉得服务器没挂就行。但实际上队列层的指标才是最能提前暴露问题的。比如消费者挂掉之后消息开始堆积这时候服务器 CPU 和内存可能完全正常但业务已经在出问题了。2.2 必须关注的六个核心指标RabbitMQ 暴露的指标有几十个但日常运维中真正需要盯紧的其实就六个。我把它们整理成了一张表方便你对照检查指标名称含义告警阈值建议为什么重要queue_messages_ready待消费消息数持续 5 分钟超过 10000直接反映消费能力是否跟得上生产速度queue_messages_unacknowledged已投递未确认消息数持续增长不下降消费者可能卡死或处理逻辑有死循环queue_consumers队列消费者数量低于预期值消费者掉线最直接的信号node_memory_used节点内存使用量超过总内存 80%触发内存告警后 RabbitMQ 会阻塞生产者node_disk_free磁盘剩余空间低于 2GB触发磁盘告警后同样会阻塞生产者connections当前连接数突增或突降 50%连接泄漏或客户端异常断开的信号这六个指标覆盖了从资源到业务的主要风险点。你不需要一开始就把所有指标都配上告警但至少要把前四个盯住。2.3 为什么选择 Prometheus Grafana 这套组合RabbitMQ 自带的管理插件确实能看到不少数据但它的短板也很明显没有历史数据存储、没有灵活的告警规则、多个节点需要逐个查看。所以生产环境我一般会搭配 Prometheus 来做指标采集和存储Grafana 做可视化Alertmanager 做告警分发。这套组合的好处在于Prometheus 的拉取模式对 RabbitMQ 很友好官方和社区都有现成的 exporterGrafana 的面板可以自定义能把队列指标和业务指标放在一起看Alertmanager 支持分组、静默、抑制避免告警风暴。注意如果你的集群节点数少于 3 个且业务量不大其实用管理插件加简单的脚本告警也能凑合。但一旦节点超过 3 个或者队列数量超过 100还是建议上 Prometheus 这套。3. 核心细节解析与实操要点3.1 管理插件的启用与关键配置RabbitMQ 的管理插件是监控的基础它提供了一个 Web UI 和 HTTP API。启用命令很简单rabbitmq-plugins enable rabbitmq_management但有几个配置项我强烈建议你调整一下默认值在生产环境往往不够用。第一个是management_agent.disable_metrics_collector。这个参数默认是false表示管理插件会定期采集指标。如果你同时用 Prometheus 采集建议把它设为true避免重复采集消耗资源。配置方式是在rabbitmq.conf里加上management_agent.disable_metrics_collector true第二个是collect_statistics_interval。默认是 5000 毫秒也就是 5 秒采集一次。如果你的队列数量很多比如超过 500 个这个频率会导致明显的 CPU 开销。可以适当调大到 10000 或 15000 毫秒collect_statistics_interval 10000第三个是 HTTP API 的访问控制。默认情况下管理插件监听 15672 端口建议只在内网开放并且通过反向代理加上认证。不要直接暴露到公网这一点每年都有团队中招。3.2 Prometheus exporter 的选型与部署RabbitMQ 的 Prometheus exporter 有两个主流选择官方的rabbitmq_prometheus插件和社区维护的独立 exporter。我的建议是优先用官方插件因为它直接内置在 RabbitMQ 里不需要额外部署进程而且指标更准确。启用命令rabbitmq-plugins enable rabbitmq_prometheus启用后RabbitMQ 会在 15692 端口暴露指标。你可以用 curl 验证一下curl -s http://localhost:15692/metrics | head -50如果能看到大量以rabbitmq_开头的指标说明配置成功了。接下来在 Prometheus 的配置文件里加上抓取任务scrape_configs: - job_name: rabbitmq static_configs: - targets: - rabbitmq-node1:15692 - rabbitmq-node2:15692 - rabbitmq-node3:15692 scrape_interval: 15s metrics_path: /metrics这里有个细节scrape_interval建议设为 15 秒不要设得太短。RabbitMQ 的指标采集本身有开销如果 Prometheus 每 5 秒抓一次在高负载下会加重节点负担。3.3 队列指标的采集粒度控制官方 exporter 默认会采集所有队列的指标这在队列数量少的时候没问题但如果你的系统有上千个队列指标基数会爆炸Prometheus 的存储和查询都会变慢。解决办法是通过配置控制采集范围。在rabbitmq.conf里可以设置prometheus.return_per_object_metrics false这个参数设为false后exporter 只返回聚合指标不返回每个队列的详细指标。如果你确实需要某些关键队列的详细数据可以通过prometheus.path自定义采集路径或者用rabbitmq_prometheus的过滤功能。我一般的做法是核心业务队列开启详细采集非核心队列只保留聚合指标。这样既能监控关键链路又不会让 Prometheus 被指标淹没。实操心得指标基数这个问题我在一个项目里踩过坑。当时系统有 2000 多个队列Prometheus 每周要吃掉 50GB 存储查询一个简单的面板要等十几秒。后来把非核心队列的详细指标关掉存储直接降到 8GB查询秒开。4. 实操过程与核心环节实现4.1 从零搭建监控环境的完整步骤假设你有一台干净的 Linux 服务器我们来一步步把监控环境搭起来。这里以单节点为例集群环境的配置类似只是 target 列表不同。第一步安装 RabbitMQ 并启用插件# 安装 RabbitMQ以常见的包管理器为例 sudo apt-get update sudo apt-get install rabbitmq-server # 启用管理插件和 Prometheus 插件 sudo rabbitmq-plugins enable rabbitmq_management sudo rabbitmq-plugins enable rabbitmq_prometheus # 重启服务使配置生效 sudo systemctl restart rabbitmq-server第二步验证指标暴露# 检查 15692 端口是否监听 ss -tlnp | grep 15692 # 抓取部分指标确认格式 curl -s http://localhost:15692/metrics | grep rabbitmq_queue_messages_ready第三步部署 Prometheus# 下载并解压 Prometheus wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz tar xvf prometheus-2.45.0.linux-amd64.tar.gz cd prometheus-2.45.0.linux-amd64编辑prometheus.yml加入 RabbitMQ 的抓取配置参考上一节的配置。然后启动./prometheus --config.fileprometheus.yml --storage.tsdb.retention.time30d这里storage.tsdb.retention.time设为 30 天表示保留 30 天的历史数据。你可以根据磁盘空间调整一般 15 到 30 天足够排查问题。第四步部署 Grafana 并导入面板# 安装 Grafana sudo apt-get install -y grafana sudo systemctl start grafana-serverGrafana 默认监听 3000 端口浏览器打开后添加 Prometheus 数据源然后导入 RabbitMQ 的官方面板。面板 ID 是 10991直接在 Grafana 的导入页面输入这个 ID 即可。4.2 关键告警规则的编写与参数计算Prometheus 的告警规则写在单独的 yml 文件里然后在prometheus.yml中引用。下面是我常用的几条规则附上参数计算过程。消息堆积告警groups: - name: rabbitmq_alerts rules: - alert: RabbitMQMessageBacklog expr: rabbitmq_queue_messages_ready 10000 for: 5m labels: severity: warning annotations: summary: 队列 {{ $labels.queue }} 消息堆积超过 10000 description: 当前待消费消息数为 {{ $value }}持续 5 分钟这里的阈值 10000 是怎么来的假设你的消费者每秒能处理 500 条消息业务能容忍的最大延迟是 20 秒那么 500 乘以 20 等于 10000。超过这个数说明消费速度已经跟不上生产速度需要人工介入。消费者掉线告警- alert: RabbitMQConsumerDown expr: rabbitmq_queue_consumers 0 for: 1m labels: severity: critical annotations: summary: 队列 {{ $labels.queue }} 没有消费者这条规则设为 1 分钟因为消费者掉线是紧急情况不能等太久。但要注意有些队列本身就是没有消费者的比如纯生产用的队列所以需要配合rabbitmq_queue_consumers的标签过滤只对业务队列生效。内存告警- alert: RabbitMQHighMemory expr: rabbitmq_node_mem_used / rabbitmq_node_mem_limit 0.8 for: 3m labels: severity: warning annotations: summary: 节点 {{ $labels.node }} 内存使用率超过 80%RabbitMQ 默认的内存告警阈值是 40%但那是相对于系统总内存的。这里我们用rabbitmq_node_mem_used除以rabbitmq_node_mem_limit得到的是相对于 RabbitMQ 自身限制的比例。超过 80% 说明离阻塞生产者不远了。4.3 Grafana 面板的定制化调整官方面板虽然全面但有些指标可能不符合你的业务场景。我一般会做三处调整第一把核心业务队列单独拉一个面板放在最上面。这样值班同学一打开就能看到关键队列的状态不用在几十个面板里找。第二增加消息进出速率的对比图。官方面板有rabbitmq_queue_messages_published_rate和rabbitmq_queue_messages_delivered_rate把这两个放在同一张图里能直观看出生产和消费是否平衡。第三增加死信队列的监控。死信队列的增长往往意味着业务逻辑有问题比如消息格式错误、消费者处理异常等。我一般会设置一个面板专门展示死信队列的消息数超过 100 就触发告警。注意Grafana 面板的查询语句要注意时间范围。如果查询范围太大比如 30 天Prometheus 的查询会非常慢。建议默认时间范围设为 6 小时需要看历史数据时再手动调整。5. 常见问题与排查技巧实录5.1 指标采集不到或数据缺失这是最常见的问题通常有三个原因。第一个原因是 exporter 没有正确启用。用rabbitmq-plugins list检查rabbitmq_prometheus是否显示为E*状态。如果不是重新启用并重启服务。第二个原因是防火墙或安全组挡住了 15692 端口。用telnet或curl从 Prometheus 所在机器测试一下连通性。第三个原因是指标基数太大导致采集超时。查看 Prometheus 的scrape_duration_seconds指标如果超过scrape_interval的 80%说明采集太慢。这时候需要减少采集的队列数量或者调大scrape_interval。5.2 告警风暴的处理告警风暴是指短时间内收到大量告警导致值班同学麻木反而忽略了真正重要的问题。RabbitMQ 监控中常见的告警风暴场景是一个节点挂了导致该节点上所有队列的指标都异常瞬间触发几十条告警。解决办法是在 Alertmanager 里配置分组和抑制规则。分组规则把同一类型的告警合并成一条通知route: group_by: [alertname, node] group_wait: 30s group_interval: 5m repeat_interval: 4h抑制规则则是在节点级别告警触发时抑制该节点上所有队列级别的告警inhibit_rules: - source_match: alertname: RabbitMQNodeDown target_match_re: alertname: RabbitMQ.* equal: [node]这样配置后节点挂了只会收到一条告警而不是几十条。5.3 内存和磁盘告警的误报RabbitMQ 的内存和磁盘告警有时候会误报尤其是在业务高峰期。比如内存使用率短暂冲到 85%但很快就降下来了。如果告警规则的for设得太短就会频繁触发。我的经验是把for设为 3 到 5 分钟给系统一个缓冲时间。同时告警阈值不要设得太激进。内存告警设 80% 而不是 70%磁盘告警设剩余 2GB 而不是 5GB。这样既能提前发现问题又不会因为正常波动而误报。另外RabbitMQ 的内存回收机制有时候会滞后。如果你发现内存使用率一直很高但业务量并不大可以手动触发一次垃圾回收rabbitmqctl eval erlang:garbage_collect().这个命令会让 Erlang 虚拟机回收不再使用的内存通常能释放不少空间。5.4 常见问题速查表问题现象可能原因排查方法解决方案指标页面空白插件未启用rabbitmq-plugins list启用rabbitmq_prometheus采集超时指标基数过大查看scrape_duration_seconds减少采集队列或调大间隔告警不触发规则表达式错误Prometheus 的 Rules 页面检查修正表达式并重载配置告警重复发送缺少分组规则检查 Alertmanager 配置添加group_by和inhibit_rules内存持续高位垃圾回收滞后rabbitmqctl status查看内存详情手动触发 GC 或调整内存阈值队列指标缺失队列被过滤检查prometheus.return_per_object_metrics调整配置或添加白名单5.5 几个容易被忽略的细节第一个细节是时间同步。Prometheus、Grafana 和 RabbitMQ 节点的时间必须同步否则指标的时间戳会对不上导致面板显示异常。建议所有节点都配置 NTP 服务。第二个细节是 Prometheus 的存储容量规划。假设你有 3 个 RabbitMQ 节点每个节点暴露 500 个指标采集间隔 15 秒那么每天产生的数据量大约是3 乘以 500 乘以 5760每天采集次数乘以 2 字节约等于 17MB。保留 30 天就是 500MB 左右。这个量不大但如果指标基数翻倍存储也会翻倍。建议定期检查 Prometheus 的存储使用情况。第三个细节是告警通知的渠道选择。邮件适合非紧急告警即时通讯工具适合紧急告警。我一般把critical级别的告警发到即时通讯工具warning级别的发邮件。这样既能保证紧急问题及时响应又不会让即时通讯工具被非紧急消息淹没。第四个细节是定期演练。监控系统搭好之后要定期模拟故障验证告警是否能正常触发。比如手动停掉一个消费者看看是否在 1 分钟内收到告警。很多团队的监控系统搭完就没人管了真出问题的时候才发现告警根本没发出来。6. 监控体系的持续优化与扩展监控不是一次性的工作而是一个持续迭代的过程。系统在变业务在变监控策略也要跟着调整。我一般每季度会做一次监控复盘看看哪些告警是误报、哪些问题没有被覆盖、哪些指标已经不再需要。比如业务调整后某些队列已经废弃了但告警规则还在就会产生噪音。及时清理这些规则能让告警系统保持敏锐。另外随着业务增长可以考虑引入分布式追踪。RabbitMQ 本身不提供消息级别的追踪但你可以通过在消息头里注入 trace ID然后在消费者端记录处理耗时从而实现端到端的延迟监控。这块内容比较多以后可以单独展开讲。最后分享一个我个人的习惯每次线上出问题之后除了修复问题本身我都会问一句“监控为什么没有提前发现”。如果是监控覆盖不到就补上对应的指标和告警如果是告警阈值不合理就调整参数。这样每次故障都变成监控体系的一次升级久而久之系统的可观测性会越来越强。

相关新闻

Python电商项目实战:Django+Flask混合架构与订单并发处理方案

Python电商项目实战:Django+Flask混合架构与订单并发处理方案

高峰期系统疯狂报警?别急,先把这套Python电商实战方案吃透从开发第一个用户注册接口,到上线前被并发打蒙,再到重构出稳定的秒杀下单流程,这些年我在电商系统这条路上踩过的坑,比喝过的咖啡都多。今天不聊那…

2026/10/12 17:58:27 阅读更多 →
非侵入式负荷分解实战:FHMM模型Python实现与避坑指南

非侵入式负荷分解实战:FHMM模型Python实现与避坑指南

简介:基于因子隐马尔可夫模型的非侵入式负荷分解资源,面向智能用电、能源管理与模式识别领域的研究者与开发者,旨在通过FHMM从家庭总用电数据中分离各电器负荷,解决非侵入式负荷监测中的关键难题。FHMM在传统隐马尔可夫模型基础上…

2026/10/12 17:58:27 阅读更多 →
Windows SDK v6.0A 安装与 VS2008 老工程编译避坑指南

Windows SDK v6.0A 安装与 VS2008 老工程编译避坑指南

简介:Microsoft Windows SDK v6.0A 是微软面向Windows平台开发者的经典工具集,主要适用于C/C、C#等语言的Win32与.NET应用程序开发,涵盖系统API接口、编译调试工具、文档示例及安装包制作组件,帮助程序员完成从编码构建到部署兼容…

2026/10/13 18:21:50 阅读更多 →

最新新闻

线上复试全流程复盘:电子信息专硕面试准备与避坑指南

线上复试全流程复盘:电子信息专硕面试准备与避坑指南

2020年的复试,对很多考研人来说都是一个特殊的节点。那年我报考了某所985高校的电子信息专硕,初试成绩出来后,一边担心复试线,一边第一次面对“线上复试”这个几乎没有先例可循的新玩法。整个复试从通知到正式进行只有不到两周的准…

2026/10/13 21:13:03 阅读更多 →
均匀分布与Wasserstein距离:40行MATLAB代码实现1D与2D计算

均匀分布与Wasserstein距离:40行MATLAB代码实现1D与2D计算

简介:这份资源是一套面向概率统计、机器学习与最优传输方向学习者的紧凑MATLAB代码,用于计算一维离散均匀概率分布之间的1-Wasserstein距离与2-Wasserstein距离。代码基于累积分布函数及其伪逆的阶跃函数表达实现,假定输入样本已按升序排列&a…

2026/10/13 21:13:03 阅读更多 →
阿里云ACP认证备考全攻略:从报名到拿证避坑指南

阿里云ACP认证备考全攻略:从报名到拿证避坑指南

进入正文。杭城某个周五晚上,我在某互联网公司做运维,群里忽然有个同事甩来一条消息:“要不要一起考个阿里云ACP?公司能报销考试费。”当时我第一反应是“考这玩意儿干啥?又不可能靠它涨工资”。后来真香了——不是因为…

2026/10/13 21:13:03 阅读更多 →
Spring Boot+Vue高校教师科研管理系统:从设计到部署全流程解析

Spring Boot+Vue高校教师科研管理系统:从设计到部署全流程解析

简介:基于 Spring Boot 与 Vue 构建的高校教师科研管理系统,是一套面向管理员、教师、学院三级用户的毕业设计源码案例,覆盖科研课题、软件著作权、论文、专利及科研成果的提交、校审与归档全流程,适合计算机相关专业学生做课设/毕…

2026/10/13 21:13:03 阅读更多 →
健身博主从零到一:定位、内容运营与变现的完整指南

健身博主从零到一:定位、内容运营与变现的完整指南

1. 健身博主从零起步的真实困境:缺的不只是内容能力这几年做博主孵化,我见过太多健身领域的内容创作者,在最初的三到六个月里就选择了放弃。他们中很多人本身练得不错,专业知识也能聊,甚至有些人已经在线下带过不少学员…

2026/10/13 21:13:03 阅读更多 →
R语言回归实战:首尔自行车需求预测与Cubist模型调优

R语言回归实战:首尔自行车需求预测与Cubist模型调优

简介:这份资源面向具备一定R语言基础、希望上手真实回归建模的数据分析学习者与从业者,围绕首尔自行车共享系统的每小时租赁需求预测展开。数据源自首尔自行车共享计划,核心目标是借助温度、时间、假期、季节等变量,预测每小时所需…

2026/10/13 21:12:02 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →