-
Notifications
You must be signed in to change notification settings - Fork 0
/
15625684305136.html
412 lines (238 loc) · 13.5 KB
/
15625684305136.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
路由中心NameServer - lazyfighter.com
</title>
<link href="atom.xml" rel="alternate" title="lazyfighter.com" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/foundation.min.css" />
<link rel="stylesheet" href="asset/css/docs.css" />
<script src="asset/js/vendor/modernizr.js"></script>
<script src="asset/js/vendor/jquery.js"></script>
<script src="asset/highlightjs/highlight.pack.js"></script>
<link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
function before_search(){
var searchVal = 'site: ' + document.getElementById('search_input').value;
document.getElementById('search_q').value = searchVal;
return true;
}
</script>
</head>
<body class="antialiased hide-extras">
<div class="marketing off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="top-bar docs-bar hide-for-small" data-topbar>
<section class="top-bar-section">
<div class="row">
<div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
<ul id="main-menu" class="left">
<li id=""><a target="self" href="index.html">Home</a></li>
<li id=""><a target="_self" href="archives.html">Archives</a></li>
</ul>
<ul class="right" id="search-wrap">
<li>
<form target="_blank" onsubmit="return before_search();" action="https://google.com/search" method="get">
<input type="hidden" id="search_q" name="q" value="" />
<input tabindex="1" type="search" id="search_input" placeholder="Search"/>
</form>
</li>
</ul>
</div></div>
</div>
</section>
</nav>
<nav class="tab-bar show-for-small">
<a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
<span> lazyfighter.com</span>
</a>
</nav>
<aside class="left-off-canvas-menu">
<ul class="off-canvas-list">
<li><a target="self" href="index.html">Home</a></li>
<li><a target="_self" href="archives.html">Archives</a></li>
<li><label>Categories</label></li>
<li><a href="spring.html">spring</a></li>
<li><a href="apache-dubbo.html">apache-dubbo</a></li>
<li><a href="Java%E7%BC%96%E7%A8%8B%E5%8F%91%E6%94%BE%E8%AE%BA%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0.html">Java编程发放论读书笔记</a></li>
<li><a href="netty.html">netty</a></li>
<li><a href="rocketmq.html">rocketmq</a></li>
<li><a href="apache-camel.html">apache-camel</a></li>
<li><a href="sofa-rpc.html">sofa-rpc</a></li>
<li><a href="java.html">java</a></li>
<li><a href="sentinel.html">sentinel</a></li>
<li><a href="react.html">react</a></li>
</ul>
</aside>
<a class="exit-off-canvas" href="#"></a>
<section id="main-content" role="main" class="scroll-container">
<script type="text/javascript">
$(function(){
$('#menu_item_index').addClass('is_active');
});
</script>
<div class="row">
<div class="large-8 medium-8 columns">
<div class="markdown-body article-wrap">
<div class="article">
<h1>路由中心NameServer</h1>
<div class="read-more clearfix">
<span class="date">2019/7/8</span>
<span>posted in </span>
<span class="posted-in"><a href='rocketmq.html'>rocketmq</a></span>
<span class="comments">
</span>
</div>
</div><!-- article -->
<div class="article-content">
<p>NameServer是RocketMQ路由管理、服务注册以及服务发现的实现。</p>
<p>消息中间件的实际思路一般基于订阅发布机制,消息生成者Producer发送某一主题的消息到消息服务器,消息服务器负责消息的持久化存储,消息消费者Consumer订阅感兴趣的主题,消息服务器根据客户端的订阅信息推送消息到消费者PUSH模式或者消息客户端主动向服务器拉取消息PULL模式,从而实现消息生产者和消息消费者的解耦。</p>
<p>为了避免消息服务器宕机导致整个消息系统瘫痪,通常会部署多台服务器,那么生产者如何知道消息发送到那台服务器,如果某台消息服务器宕机如何能够被生产者感知,NameServer就是为了解决上述的问题。</p>
<span id="more"></span><!-- more -->
<h2 id="toc_0">NameServer架构设计</h2>
<p>Broker消息服务器在启动的时候向所有的NameServer注册,消息生产者在发送消息之前先从NameServer获取Broker服务器地址列表,然后根据负载均衡算法选一台消息服务器进行消息发送,NameServer与每台Broker服务器保持长连接,并间隔30S检查Broker是否存活,如果检测到宕机,则从路由注册表移除,但是不会马上通知生产者,而是由发送端保证发送的高可用。</p>
<p>NameServer本身的高可用是通过部署多台来实现,但是彼此之间不会进行通信。也就是某一时刻多台的NameServer的数据不会一致,但是不会对发送消息造成任何影响。</p>
<h2 id="toc_1">NameServer的启动流程</h2>
<ol>
<li>根据启动参数指定的configFile,通过指定读入<code>Properties</code>中,然后通过反射调用填充<code>NameServerConfig</code>、<code>NettyServerConfig</code>属性值此处默认端口为9876.</li>
<li>是否设置Print参数,如果设置打印填充完成后的对象中的属性,然后退出。</li>
<li>构造<code>NamesrvController</code>, 合并配置文件,并初始化该实例</li>
<li>加载kvconfig到内存中</li>
<li>创建<code>NettyRemotingServer</code>网络处理对象, 构造业务线程池,同时将处理器注册到server中。</li>
<li>启动定时任务每10s中扫描一次Broker移除不处于激活状态的Broker</li>
<li>启动定时任务每10s中打印一次kv配置</li>
<li>根据用户是否启用SSL配置SSL信息</li>
<li>注册JVM钩子函数,进行优雅关闭</li>
<li>启动SSL文件监听,启动服务器监听Broker以及消息生产者的网络请求。</li>
</ol>
<h2 id="toc_2">NameServer路由注册、故障剔除</h2>
<p>NameServer主要作用是为消息生产者和消息消费者提供关于主题Topic的路由信息那么NameServer就需要能够存储路由的基础信息,还要能够管理Broker节点包含路由注册路由删除等功能。</p>
<h3 id="toc_3">路由元信息</h3>
<p>路由元信息具体实现类<code>org.apache.rocketmq.namesrv.routeinfo.RouteInfoManager</code>主要存储如下信息</p>
<pre><code class="language-java">private final HashMap<String/* topic */, List<QueueData>> topicQueueTable;
private final HashMap<String/* brokerName */, BrokerData> brokerAddrTable;
private final HashMap<String/* clusterName */, Set<String/* brokerName */>> clusterAddrTable;
private final HashMap<String/* brokerAddr */, BrokerLiveInfo> brokerLiveTable;
private final HashMap<String/* brokerAddr */, List<String>/* Filter Server */> filterServerTable;
</code></pre>
<ul>
<li>topicQueueTable: Topic消息队列路由信息,消息发送时根据路由表进行负载均衡</li>
<li>brokerAddrTable: Broker基础信息,包含brokerName、所属集群名称、主备Broker地址</li>
<li>clusterAddrTable: Broker集群消息,存储集群中所有Broker名称</li>
<li>brokerLiveTable: Broker状态信息,NameServer每次收到心跳包会替换该信息</li>
<li>filterServerTable: Broker上的FilterServer列表,用于类模式消息过滤。</li>
</ul>
<p>RocketMQ基于订阅发布机制,一个Topic拥有多个消息队列,一个Broker为每一主题默认创建4个读队列4个写队列。多个Broker组成一个集群,BrokerName相同的组成Master-Slave架构,brokerid为0的代表Master大于0的为Slave。</p>
<h3 id="toc_4">路由注册</h3>
<p>RocketMQ路由注册是通过Broker与NameServer的心跳功能实现的,Broker启动的时候向集群中所有的NameServer发送心跳语句,每隔30s向集群中所有的NameServer发送心跳包,NameServer收到Broker的心跳包就会更新brokerLiveTable缓存中的BrokerLiveInfo的lastUpdateTimestamp,然后NameServer每10s扫描brokerLiveTable,如果持续120s没有心跳包则移除Broker的路由信息同时关闭Socket连接。</p>
</div>
<div class="row">
<div class="large-6 columns">
<p class="text-left" style="padding:15px 0px;">
<a href="15625738990440.html"
title="Previous Post: Broker启动流程">« Broker启动流程</a>
</p>
</div>
<div class="large-6 columns">
<p class="text-right" style="padding:15px 0px;">
<a href="15625659827923.html"
title="Next Post: RocketMQ概览">RocketMQ概览 »</a>
</p>
</div>
</div>
<div class="comments-wrap">
<div class="share-comments">
</div>
</div>
</div><!-- article-wrap -->
</div><!-- large 8 -->
<div class="large-4 medium-4 columns">
<div class="hide-for-small">
<div id="sidebar" class="sidebar">
<div id="site-info" class="site-info">
<div class="site-a-logo"><img src="https://pic.wenwen.soso.com/p/20141016/20141016170205-https://pic.wenwen.soso.com/p/20141016/20141016170205-1919883500.jpg" /></div>
<h1>lazyfighter.com</h1>
<div class="site-des"></div>
<div class="social">
<a target="_blank" class="github" target="_blank" href="https://github.com/lazyfighter" title="GitHub">GitHub</a>
<a target="_blank" class="email" href="mailto:[email protected]" title="Email">Email</a>
<a target="_blank" class="rss" href="atom.xml" title="RSS">RSS</a>
</div>
</div>
<div id="site-categories" class="side-item ">
<div class="side-header">
<h2>Categories</h2>
</div>
<div class="side-content">
<p class="cat-list">
<a href="spring.html"><strong>spring</strong></a>
<a href="apache-dubbo.html"><strong>apache-dubbo</strong></a>
<a href="Java%E7%BC%96%E7%A8%8B%E5%8F%91%E6%94%BE%E8%AE%BA%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0.html"><strong>Java编程发放论读书笔记</strong></a>
<a href="netty.html"><strong>netty</strong></a>
<a href="rocketmq.html"><strong>rocketmq</strong></a>
<a href="apache-camel.html"><strong>apache-camel</strong></a>
<a href="sofa-rpc.html"><strong>sofa-rpc</strong></a>
<a href="java.html"><strong>java</strong></a>
<a href="sentinel.html"><strong>sentinel</strong></a>
<a href="react.html"><strong>react</strong></a>
</p>
</div>
</div>
<div id="site-categories" class="side-item">
<div class="side-header">
<h2>Recent Posts</h2>
</div>
<div class="side-content">
<ul class="posts-list">
<li class="post">
<a href="15625738990440.html">Broker启动流程</a>
</li>
<li class="post">
<a href="15625684305136.html">路由中心NameServer</a>
</li>
<li class="post">
<a href="15625659827923.html">RocketMQ概览</a>
</li>
<li class="post">
<a href="15621422737770.html">通过消息头中定义长度字段来标识消息的总长度</a>
</li>
<li class="post">
<a href="15620535102889.html">第1章 响应式编程总览</a>
</li>
</ul>
</div>
</div>
</div><!-- sidebar -->
</div><!-- hide for small -->
</div><!-- large 4 -->
</div><!-- row -->
<div class="page-bottom clearfix">
<div class="row">
<p class="copyright">Copyright © 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
</div>
</div>
</section>
</div>
</div>
<script src="asset/js/foundation.min.js"></script>
<script>
$(document).foundation();
function fixSidebarHeight(){
var w1 = $('.markdown-body').height();
var w2 = $('#sidebar').height();
if (w1 > w2) { $('#sidebar').height(w1); };
}
$(function(){
fixSidebarHeight();
})
$(window).load(function(){
fixSidebarHeight();
});
</script>
</body>
</html>