learn.lianglianglee.com/专栏/RocketMQ 实战与进阶(完)/24 RocketMQ-Console 常用页面指标获取逻辑.md.html
2022-08-14 03:40:33 +08:00

261 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>24 RocketMQ-Console 常用页面指标获取逻辑.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/01 搭建学习环境准备篇.md.html">01 搭建学习环境准备篇</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/02 RocketMQ 核心概念扫盲篇.md.html">02 RocketMQ 核心概念扫盲篇</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/03 消息发送 API 详解与版本变迁说明.md.html">03 消息发送 API 详解与版本变迁说明</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/04 结合实际应用场景谈消息发送.md.html">04 结合实际应用场景谈消息发送</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/05 消息发送核心参数与工作原理详解.md.html">05 消息发送核心参数与工作原理详解</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/06 消息发送常见错误与解决方案.md.html">06 消息发送常见错误与解决方案</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/07 事务消息使用及方案选型思考.md.html">07 事务消息使用及方案选型思考</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/08 消息消费 API 与版本变迁说明.md.html">08 消息消费 API 与版本变迁说明</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/09 DefaultMQPushConsumer 核心参数与工作原理.md.html">09 DefaultMQPushConsumer 核心参数与工作原理</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/10 DefaultMQPushConsumer 使用示例与注意事项.md.html">10 DefaultMQPushConsumer 使用示例与注意事项</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/11 DefaultLitePullConsumer 核心参数与实战.md.html">11 DefaultLitePullConsumer 核心参数与实战</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/12 结合实际场景再聊 DefaultLitePullConsumer 的使用.md.html">12 结合实际场景再聊 DefaultLitePullConsumer 的使用</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/13 结合实际场景顺序消费、消息过滤实战.md.html">13 结合实际场景顺序消费、消息过滤实战</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/14 消息消费积压问题排查实战.md.html">14 消息消费积压问题排查实战</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/15 RocketMQ 常用命令实战.md.html">15 RocketMQ 常用命令实战</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/16 RocketMQ 集群性能摸高.md.html">16 RocketMQ 集群性能摸高</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/17 RocketMQ 集群性能调优.md.html">17 RocketMQ 集群性能调优</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/18 RocketMQ 集群平滑运维.md.html">18 RocketMQ 集群平滑运维</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/19 RocketMQ 集群监控(一).md.html">19 RocketMQ 集群监控(一)</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/20 RocketMQ 集群监控(二).md.html">20 RocketMQ 集群监控(二)</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/21 RocketMQ 集群告警.md.html">21 RocketMQ 集群告警</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/22 RocketMQ 集群踩坑记.md.html">22 RocketMQ 集群踩坑记</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/23 消息轨迹、ACL 与多副本搭建.md.html">23 消息轨迹、ACL 与多副本搭建</a>
</li>
<li>
<a class="current-tab" href="/专栏/RocketMQ 实战与进阶(完)/24 RocketMQ-Console 常用页面指标获取逻辑.md.html">24 RocketMQ-Console 常用页面指标获取逻辑</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/25 RocketMQ Nameserver 背后的设计理念.md.html">25 RocketMQ Nameserver 背后的设计理念</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/26 Java 并发编程实战.md.html">26 Java 并发编程实战</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/27 从 RocketMQ 学基于文件的编程模式(一).md.html">27 从 RocketMQ 学基于文件的编程模式(一)</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/28 从 RocketMQ 学基于文件的编程模式(二).md.html">28 从 RocketMQ 学基于文件的编程模式(二)</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/29 从 RocketMQ 学 Netty 网络编程技巧.md.html">29 从 RocketMQ 学 Netty 网络编程技巧</a>
</li>
<li>
<a href="/专栏/RocketMQ 实战与进阶(完)/30 RocketMQ 学习方法之我见.md.html">30 RocketMQ 学习方法之我见</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>24 RocketMQ-Console 常用页面指标获取逻辑</h1>
<p>本文的目的不是详细介绍 RocketMQ-Console 的使用方法,<strong>主要对一些关键点(更多是会有疑问的点)进行介绍</strong>,避免对返回结果进行想当然。</p>
<h3>集群信息一览</h3>
<p><img src="assets/2020092021571568.png" alt="1" /></p>
<p>可以通过 Cluster 查看一个集群中所有的 Broker 信息,包含主节点、从节点,有时候发现主节点、从节点的一些统计指标存在一些偏差,例如 Slave 节点的 Today Producer Count 比主节点的低或者高,会简单认为出现错误,其实大可不必太在意,说明如下:</p>
<p>RocketMQ 的数据统计是基于时间窗口,并且数据是存储在内存中,一旦 Broker 节点重启,所有的监控数据都将丢失,而且主从同步数据存在时延,统计不一致很正常。如果主 Broker 节点重启过,统计中的数据会少于从节点,同样如果从 Broker 节点重启过,主节点就会超过从节点。</p>
<h3>消费 TPS 只统计主节点</h3>
<p><img src="assets/20200920215723784.png" alt="2" /></p>
<p>在 Consumer 的菜单中,显示的 TPS 表示的消息消费 TPS但值得注意的是数据只来源于主节点并不会统计从节点的数据笔者有一次碰的一个消费端问题需要重置消费端的位点到几天前显示的效果是 Delay消息积压会减少但 TPS 一直为 0这就是因为重置位点后出发了消息消费时切换到了从节点导致从节点上的消费 TPS 并没有被统计。</p>
<h3>RocketMQ msgId</h3>
<p><img src="assets/20200920215731562.png" alt="3" /></p>
<p>在 RocketMQ 中存在两个消息 IDoffsetMsgId记录了消息的物理偏移量等信息、msgId消息全局唯一 ID那在该列表中返回的消息的 ID 是哪个 ID 呢?这里显示的是 msgId。</p>
<p>在根据 MESSAGE ID 进行消息查找时,下面这个界面即可用输入 msgId 也可以输入 offsetMsgID 进行查询。其操作界面如下:</p>
<p><img src="assets/20200920215739154.png" alt="4" /></p>
<p>那这里又是为什么呢?这个是因为 RocketMQ-Console 做了兼容,会首先尝试按照 offsetMsgId 去查询,如果查询失败,则再次使用 msgId 去快速查询。通过 offsetMsgId 能快速查询到消息这个不奇怪,因为 offsetMsgID 中包含了 Broker 的 IP 地址与端口号以及物理偏移量,那如何根据 msgId 快速检索消息呢?答案是通过 Hash 索引,全局唯一 ID 在 RocketMQ 中 msgId 的另外一个名词叫 UNIQ_KEY会存入 index 索引文件中。</p>
<h3>创建订阅关系</h3>
<p>在 RocketMQ 中不仅可以关闭自动创建主题,其实还可以关闭自动创建消费组,可通过设置属性 autoCreateSubscriptionGroup 为 false 关闭自动创建消费组,这样必须先通过命令或界面手工创建消费组,项目组才能使用该消费组用来消费消息,在生产环境中建议将其设置为 false这样更加管控性在 RocketMQ 中可以通过该界面添加消费组订阅信息:</p>
<p><img src="assets/20200920215848554.png" alt="5" /></p>
<h3>关于 RocketMQ-Console 中的 lastTimestamp 时间说明</h3>
<p><img src="assets/20200920215856374.png" alt="6" /></p>
<p>通常大家会看到 lastTimestamp 的时间会显示 1970 年,这是为什么呢?</p>
<p>首先 lastTimestamp 在“查看消息消费进度”时表示的意思是当前消费到的消息的存储时间,<strong>即消息消费进度中当前的偏移量对应的消息在 Broker 中的存储时间</strong>。再结合 RocketMQ 消息消费过期删除机制,默认一条消息只存储 3 天,三天过后这条消息会被删除,如果此时一直没有消费,消息消费进度代表的<strong>当前偏移量所对应的消息已被删除</strong>,则会显示 1970。</p>
<p>RocketMQ 的使用还是比较简单的,<strong>本文重点展示的是一些容易引起“误会”的点</strong>,暂时想到就只有如上如果大家对 RocketMQ-Console 的使用有有其他一些疑问,欢迎大家加入到官方创建的微信群。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/RocketMQ 实战与进阶(完)/23 消息轨迹、ACL 与多副本搭建.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/RocketMQ 实战与进阶(完)/25 RocketMQ Nameserver 背后的设计理念.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997448fb673d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>