mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-26 05:06:42 +08:00
261 lines
16 KiB
HTML
261 lines
16 KiB
HTML
<!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 中存在两个消息 ID,offsetMsgId(记录了消息的物理偏移量等信息)、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>
|