-
Notifications
You must be signed in to change notification settings - Fork 1
/
ribbon.drawio
552 lines (552 loc) · 85.6 KB
/
ribbon.drawio
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
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
<mxfile host="Electron" modified="2024-05-02T14:13:07.826Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.5 Chrome/114.0.5735.243 Electron/25.3.1 Safari/537.36" etag="HVS6tTHB7rEEVDNc6KQo" version="21.6.5" type="device">
<diagram name="第 1 页" id="s7ftlZovgMCbnuo22AY1">
<mxGraphModel dx="2768" dy="842" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="8GXi-stoHSAcCtSXBaf--1" value="<b>URLConnectionLoadBalancerExample</b><br>使用LoadBalancerCommand通过固定Server列表的负载均衡器和HttpURLConnection发送请求的示例。" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="40" y="20" width="480" height="50" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--2" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--3" target="8GXi-stoHSAcCtSXBaf--6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--3" value="List&lt;Server&gt; servers =&nbsp;<br style="font-size: 10px;">Lists.newArrayList(new Server(...), ...)<br><font color="#007fff"><b>获取服务节点列表</b>,企业级应用一般是从注册中心通过服务名获取的</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="40" y="80" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--6" target="8GXi-stoHSAcCtSXBaf--10">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--6" target="8GXi-stoHSAcCtSXBaf--93">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--6" value="URLConnectionLoadBalancer <b>urlLoadBalancer</b> = new URLConnectionLoadBalancer(servers);<br>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="40" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--7" value="<div style="text-align: center;"><font color="#000000">com.netflix.loadbalancer.</font><b style="font-size: 10px; color: rgb(0, 0, 0); background-color: initial;">Server</b></div><hr style="font-size: 10px;" size="1"><font style="font-size: 10px;"><span style="background-color: initial;">服务端服务实例描述对象<br><div style=""><span style="color: rgb(0, 0, 0); background-color: initial;"><br></span></div><div style=""><span style="color: rgb(0, 0, 0); background-color: initial;">private String <b>host</b>;</span><br></div><div style=""><font style="font-size: 10px;" color="#000000"><span style="font-size: 10px;"><div>private int <b>port</b>;</div><div>private String <b>scheme</b>;</div><div>private volatile String <b>id</b>;</div><div>private volatile boolean isAliveFlag;</div><div>private String zone;</div><div>private volatile boolean readyToServe;</div><div>private MetaInfo simpleMetaInfo;</div></span></font></div></span></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fontColor=#007FFF;" vertex="1" parent="1">
<mxGeometry x="-320" y="80" width="280" height="240" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--8" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--10" target="8GXi-stoHSAcCtSXBaf--16">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--9" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--10" target="8GXi-stoHSAcCtSXBaf--13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--10" value="loadBalancer = LoadBalancerBuilder.newBuilder()<br>.<b>buildFixedServerListLoadBalancer</b>(<br>serverList);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="280" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--13" target="8GXi-stoHSAcCtSXBaf--33">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--12" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--13" target="8GXi-stoHSAcCtSXBaf--42">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--13" value="<div>if (rule == null) {</div><div><font style="font-size: 9px;">&nbsp; &nbsp; rule = createRuleFromConfig(config, factory);</font></div><div>}</div><div><font color="#007fff">创建负载均衡规则,根据实际加载的配置</font></div><font color="#007fff">NFLoadBalancerRuleClassName&nbsp;</font><span style="color: rgb(0, 127, 255); background-color: initial;">创建</span><font color="#007fff"><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#fff2cc;strokeColor=#d6b656;align=left;" vertex="1" parent="1">
<mxGeometry x="520" y="400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--14" value="<div style="text-align: center;"><font color="#000000">com.netflix.loadbalancer.</font><b style="font-size: 10px; color: rgb(0, 0, 0); background-color: initial;">LoadBalancerBuilder</b></div><hr style="font-size: 10px;" size="1"><font style="font-size: 10px;"><span style="background-color: initial;">服务端服务实例描述对象<br><div style=""><span style="color: rgb(0, 0, 0); background-color: initial;"><br></span></div><div style=""><span style="background-color: initial;">//负载均衡器配置</span></div><div style=""><div><font color="#000000">private IClientConfig <b>config</b> = ClientConfigFactory</font></div><div><font color="#000000"><span style="white-space: pre;">	</span>.findDefaultConfigFactory().newConfig();</font></div><div><font color="#000000">private ServerListFilter <b>serverListFilter</b>;</font></div><div>//配置中定义的负载均衡规则</div><div><font color="#000000">private IRule <b>rule</b>;</font></div><div><font color="#000000">private IPing ping = new DummyPing();</font></div><div><font color="#000000">private ServerList <b>serverListImpl</b>;</font></div><div><font color="#000000">private ServerListUpdater serverListUpdater;</font></div><div>//传入类名,根据客户端配置config 实例化类</div><div><font color="#000000">private IClientConfigAware.Factory <b>factory</b> =&nbsp;</font></div><div><font color="#000000"><span style="white-space: pre;">	</span>ClientFactory::instantiateInstanceWithClientConfig;</font></div></div></span></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fontColor=#007FFF;" vertex="1" parent="1">
<mxGeometry x="-720" y="80" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--15" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--16" target="8GXi-stoHSAcCtSXBaf--21">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--16" value="IClientConfig config = ClientConfigFactory<br>.findDefaultConfigFactory().newConfig();<br><font color="#007fff">如过没其他提名默认加载配置 <b>DefaultClientConfigImpl</b></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" vertex="1" parent="1">
<mxGeometry x="520" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--17" value="LoadBalancerBuilder" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="555" y="130" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--18" value="<b>FeignOptionsClientConfig</b><br><font color="#007fff">SpringCloudFeign中重写了ribbon-core中默认配置类DefaultClientConfigImpl,参考 spring-cloud-openfeign-core<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="1241" y="320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--19" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--21" target="8GXi-stoHSAcCtSXBaf--26">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--20" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--21" target="8GXi-stoHSAcCtSXBaf--28">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--21" value="<b>SPI机制</b>加载&nbsp;<b>ClientConfigFactory</b>.class<br>并按&nbsp;getPriority() 方法返回的优先级排序,返回优先级最高的" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="760" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--22" value="<font style="" color="#007fff">如果引入了ribbon-archaius,会提名com.netflix.client.config.ArchaiusClientConfigFactory<br><span style="font-size: 10px;">(<b>注意</b>创建的配置类名字也是DefaultClientConfigImpl</span><span style="font-size: 10px;">但是和ribbon-core中的类不是同一个类)</span><br><span style="font-size: 10px;">如果没有提名,默认使用 DefaultClientConfigFactory</span><br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1440.5" y="160" width="490" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--23" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endArrow=diamondThin;endFill=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--24" target="8GXi-stoHSAcCtSXBaf--14">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--24" value="<div style="text-align: center; font-size: 11px;"><font style="font-size: 11px;"><font style="font-size: 11px;" color="#000000">ribbon-<b style="">archaius</b>&nbsp;</font><font style="background-color: initial; font-size: 11px;" color="#000000">com.netflix.client.config</font><span style="background-color: initial; color: rgb(0, 0, 0);">.</span><b style="background-color: initial; color: rgb(0, 0, 0);">DefaultClientConfigImpl</b></font></div><hr style="font-size: 11px;" size="1"><font style=""><span style="background-color: initial; font-size: 10px;">默认的负载均衡器配置</span><br><span style="background-color: initial;"><div style=""><div style=""><font color="#000000"><span style="font-size: 10px;">propertyNameSpace = "ribbon"</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">vipResolver = null</span></font></div><div style=""><span style="font-size: 10px;">//</span></div><div style=""><font color="#000000"><span style="font-size: 10px;">internalProperties = {ConcurrentHashMap@1071}&nbsp; size = 0</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">dynamicProperties = {ConcurrentHashMap@1072}&nbsp; size = 0</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">changeActions = {ConcurrentHashMap@1073}&nbsp; size = 0</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">refreshCounter = {AtomicLong@1074} "0"</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">resolver = {ArchaiusPropertyResolver@1075}&nbsp;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">clientName = ""</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">namespace = "ribbon"</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">isDynamic = false</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">cachedToString = "ClientConfig:"</span></font></div></div></span></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fontColor=#007FFF;" vertex="1" parent="1">
<mxGeometry x="-1120" y="80" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--25" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--26" target="8GXi-stoHSAcCtSXBaf--29">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--26" value="<b>ArchaiusClientConfigFactory</b>#<br>newConfig()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" vertex="1" parent="1">
<mxGeometry x="1000" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--28" target="8GXi-stoHSAcCtSXBaf--30">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--28" value="<b>DefaultClientConfigFactory</b>#<br>newConfig()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" vertex="1" parent="1">
<mxGeometry x="1000" y="240" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--29" value="<b>DefaultClientConfigImpl</b><br>extends AbstractDefaultClientConfigImpl<br>extends ReloadableClientConfig<br>implements IClientConfig<br><font color="#007fff">测试DEMO中加载的这个配置</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="1241" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--30" value="<b>DefaultClientConfigImpl</b><br>implements IClientConfig" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="1240.5" y="240" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--33" target="8GXi-stoHSAcCtSXBaf--34">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--33" target="8GXi-stoHSAcCtSXBaf--36">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--33" value="<div style=""><font size="1">String ruleClassName = config.getOrDefault(IClientConfigKey.Keys.<br>NFLoadBalancerRuleClassName);</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="760" y="400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--34" value="<div style="font-size: 9px;">NFLoadBalancerRuleClassName = new <b>CommonClientConfigKey</b>&lt;String&gt;("NFLoadBalancerRuleClassName", "com.netflix.loadbalancer.<b style="border-color: var(--border-color);">AvailabilityFilteringRule</b>") {<span style="background-color: initial;">};</span></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="990" y="400" width="220" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--35" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--36" target="8GXi-stoHSAcCtSXBaf--38">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--36" value="<div style=""><font size="1">rule = (IRule) factory.create(ruleClassName, config);</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" vertex="1" parent="1">
<mxGeometry x="760" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--37" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--38" target="8GXi-stoHSAcCtSXBaf--135">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--38" value="<div style=""><font size="1">AvailabilityFilteringRule</font><br></div><div style=""><font color="#3333ff" size="1">继承</font></div><font color="#3333ff" size="1">ClientConfigEnabledRoundRobinRule</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--39" value="<div style=""><font size="1">BestAvailableRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="560" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--40" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;align=center;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--42" target="8GXi-stoHSAcCtSXBaf--43">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--41" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--42" target="8GXi-stoHSAcCtSXBaf--89">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--42" value="<div></div>BaseLoadBalancer lb = new BaseLoadBalancer(config, rule, ping);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="520" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--43" value="<div></div>lb.<b>setServersList</b>(servers);<br>return lb;" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="520" y="1360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--44" value="<div style=""><font size="1">ClientConfigEnabledRoundRobinRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="640" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--45" value="<div style=""><font size="1">RandomRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--46" value="<div style=""><font size="1">ResponseTimeWeightedRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--47" value="<div style=""><font size="1">RetryRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="880" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--49" target="8GXi-stoHSAcCtSXBaf--145">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--49" value="<div style=""><font size="1">RoundRobinRule</font><br></div><div style=""><font color="#007fff" size="1">轮询</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--50" value="<div style=""><font size="1">WeightedResponseTimeRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="1040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--51" value="<div style=""><font size="1">ZoneAvoidanceRule</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="1120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--52" value="<div style=""><font size="1">NacosRule</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1000" y="1200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--53" value="" style="shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;labelPosition=left;verticalLabelPosition=middle;align=right;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="980" y="480" width="10" height="700" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--54" value="<font color="#007fff" style="font-size: 10px;">ribbon-core<br>定义的负载均衡规则</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="880" y="810" width="110" height="40" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--55" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>AbstractLoadBalancerRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" vertex="1" parent="1">
<mxGeometry x="-665" y="441" width="235" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--56" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>AvailabilityFilteringRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-954" y="684" width="214" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--57" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>BestAvailableRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-842" y="620" width="174" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--58" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ClientConfigEnabledRoundRobinRule</b></p><hr size="1"><font style="font-size: 10px;">&nbsp;RoundRobinRule <b>roundRobinRule</b> = new RoundRobinRule();</font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-1006" y="522" width="310" height="58" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--59" value="<p style="margin:0px;margin-top:4px;text-align:center;"><i>&lt;&lt;interface&gt;&gt;</i><br/><b>IRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="-590" y="360" width="85" height="39" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--60" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>PredicateBasedRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" vertex="1" parent="1">
<mxGeometry x="-1052" y="620" width="190" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--61" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>RandomRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-537" y="522" width="140" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--62" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ResponseTimeWeightedRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-556" y="603" width="248" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--63" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>RetryRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-676" y="522" width="119" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--64" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>RoundRobinRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-377" y="522" width="168" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--65" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>WeightedResponseTimeRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-288" y="603" width="248" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--66" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ZoneAvoidanceRule</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-1162" y="684" width="188" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--67" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=#008200;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--55" target="8GXi-stoHSAcCtSXBaf--59">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--68" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--56" target="8GXi-stoHSAcCtSXBaf--60">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-847" y="670" />
<mxPoint x="-957" y="670" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--69" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--57" target="8GXi-stoHSAcCtSXBaf--58">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-755" y="600" />
<mxPoint x="-851" y="600" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--70" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--58" target="8GXi-stoHSAcCtSXBaf--55">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-851" y="497" />
<mxPoint x="-547" y="497" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--71" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--60" target="8GXi-stoHSAcCtSXBaf--58">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-957" y="600" />
<mxPoint x="-851" y="600" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--72" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--61" target="8GXi-stoHSAcCtSXBaf--55">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-467" y="497" />
<mxPoint x="-547" y="497" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--73" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--62" target="8GXi-stoHSAcCtSXBaf--64">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-432" y="578" />
<mxPoint x="-293" y="578" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--74" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--63" target="8GXi-stoHSAcCtSXBaf--55">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-617" y="497" />
<mxPoint x="-547" y="497" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--75" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--64" target="8GXi-stoHSAcCtSXBaf--55">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-293" y="497" />
<mxPoint x="-547" y="497" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--76" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--65" target="8GXi-stoHSAcCtSXBaf--64">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-164" y="578" />
<mxPoint x="-293" y="578" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--77" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--66" target="8GXi-stoHSAcCtSXBaf--60">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1068" y="670" />
<mxPoint x="-957" y="670" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--78" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>AbstractLoadBalancer</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" vertex="1" parent="1">
<mxGeometry x="-466" y="762" width="204" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--79" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>BaseLoadBalancer (核心类)</b></p><hr size="1"><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//默认RoundRobinRule</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected <b>IRule</b> <b>rule</b> = DEFAULT_RULE;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//默认SerialPingStrategy</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected IPingStrategy <b>pingStrategy</b> = DEFAULT_PING_STRATEGY;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected IPing <b>ping</b> = null;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">@Monitor(name = PREFIX + "AllServerList", type = DataSourceType.INFORMATIONAL)</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//所有服务实例列表</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected volatile List&lt;Server&gt; <b>allServerList</b> = Collections</font><span style="background-color: initial;">.synchronizedList(new ArrayList&lt;Server&gt;());</span></div><div style="font-size: 10px;"><font style="font-size: 10px;">@Monitor(name = PREFIX + "UpServerList", type = DataSourceType.INFORMATIONAL)</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//可用的服务实例列表</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected volatile List&lt;Server&gt; <b>upServerList</b> = Collections</font><span style="background-color: initial;">.synchronizedList(new ArrayList&lt;Server&gt;());</span></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected ReadWriteLock <b>allServerLock</b> = new ReentrantReadWriteLock();</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected ReadWriteLock <b>upServerLock</b> = new ReentrantReadWriteLock();</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">//默认default</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected String <b>name</b> = DEFAULT_NAME;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected Timer <b>lbTimer</b> = null;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected int <b>pingIntervalSeconds</b> = 10;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected int <b>maxTotalPingTimeSeconds</b> = 5;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected Comparator&lt;Server&gt; <b>serverComparator</b> = new ServerComparator();</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected AtomicBoolean <b>pingInProgress</b> = new AtomicBoolean(false);</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">protected LoadBalancerStats <b>lbStats</b>;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private volatile Counter <b>counter</b> = Monitors.newCounter("LoadBalancer_ChooseServer");</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private PrimeConnections <b>primeConnections</b>;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private volatile boolean <b>enablePrimingConnections</b> = false;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private IClientConfig <b>config</b>;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private List&lt;ServerListChangeListener&gt; <b>changeListeners</b> = new CopyOnWriteArrayList&lt;ServerListChangeListener&gt;();</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">private List&lt;ServerStatusChangeListener&gt; <b>serverStatusListeners</b> =&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;"><span style=""><span style="white-space: pre;">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>new CopyOnWriteArrayList&lt;ServerStatusChangeListener&gt;();</font></div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-570" y="841" width="530" height="379" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--80" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>DynamicServerListLoadBalancer<T></b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-456.5" y="1240" width="303" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--81" value="<p style="margin:0px;margin-top:4px;text-align:center;"><i>&lt;&lt;interface&gt;&gt;</i><br/><b>ILoadBalancer</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="-438" y="681" width="149" height="39" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--82" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>NoOpLoadBalancer</b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-800" y="840" width="185" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--83" value="<p style="margin:0px;margin-top:4px;text-align:center;"><b>ZoneAwareLoadBalancer<T></b></p><hr size="1"/>" style="verticalAlign=top;align=left;overflow=fill;fontSize=14;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="-430" y="1310" width="250" height="33" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--84" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=#008200;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--78" target="8GXi-stoHSAcCtSXBaf--81">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--85" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--79" target="8GXi-stoHSAcCtSXBaf--78">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-305" y="818" />
<mxPoint x="-364" y="818" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--86" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--80" target="8GXi-stoHSAcCtSXBaf--79">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
<mxPoint x="-305" y="1230" as="sourcePoint" />
<mxPoint x="-295" y="1340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--87" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--82" target="8GXi-stoHSAcCtSXBaf--78">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-707" y="818" />
<mxPoint x="-364" y="818" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--88" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=#000082;entryX=0.500;entryY=1.001;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--83" target="8GXi-stoHSAcCtSXBaf--80">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
<mxPoint x="-305" y="1330" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--89" value="<div></div>initWithConfig(config, rule, ping, createLoadBalancerStatsFromConfig(config, ClientFactory<br>::instantiateInstanceWithClientConfig));" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" vertex="1" parent="1">
<mxGeometry x="760" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--90" value="<div style="font-size: 10px;"><div><font color="#007fff">rule = {AvailabilityFilteringRule@1239}&nbsp;</font></div><div><font color="#007fff">pingStrategy = {BaseLoadBalancer$SerialPingStrategy@1255}&nbsp;</font></div><div><font color="#007fff">ping = {DummyPing@1082}&nbsp;</font></div><div><font color="#007fff">allServerList = {ArrayList@1962}&nbsp; size = 3</font></div><div><font color="#007fff">upServerList = {ArrayList@1962}&nbsp; size = 3</font></div><div><font color="#007fff">allServerLock = {ReentrantReadWriteLock@1267} "java.util.concurrent.locks.ReentrantReadWriteLock@473b46c3[Write locks = 0, Read locks = 0]"</font></div><div><font color="#007fff">upServerLock = {ReentrantReadWriteLock@1270} "java.util.concurrent.locks.ReentrantReadWriteLock@516be40f[Write locks = 0, Read locks = 0]"</font></div><div><font color="#007fff">name = ""</font></div><div><font color="#007fff">lbTimer = null</font></div><div><font color="#007fff">pingIntervalSeconds = 30</font></div><div><font color="#007fff">maxTotalPingTimeSeconds = 2</font></div><div><font color="#007fff">serverComparator = {ServerComparator@1283}&nbsp;</font></div><div><font color="#007fff">pingInProgress = {AtomicBoolean@1287} "false"</font></div><div><font color="#007fff">lbStats = {LoadBalancerStats@1402} "Zone stats: {},Server stats: []"</font></div><div><font color="#007fff">counter = {BasicCounter@1311} "BasicCounter{config=MonitorConfig{name=LoadBalancer_ChooseServer, tags=COUNTER, policy=DefaultPublishingPolicy}, count=0}"</font></div><div><font color="#007fff">primeConnections = null</font></div><div><font color="#007fff">enablePrimingConnections = false</font></div><div><font color="#007fff">config = {DefaultClientConfigImpl@1039} "ClientConfig:"</font></div><div><font color="#007fff">changeListeners = {CopyOnWriteArrayList@1317}&nbsp; size = 0</font></div><div><font color="#007fff">serverStatusListeners = {CopyOnWriteArrayList@1320}&nbsp; size = 0</font></div></div>" style="text;html=1;align=left;verticalAlign=top;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="740" y="1360" width="770" height="250" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--93" target="8GXi-stoHSAcCtSXBaf--94">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--92" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--93" target="8GXi-stoHSAcCtSXBaf--99">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--93" value="urlLoadBalancer.call("/")" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="40" y="1620" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--94" value="urlLoadBalancer.getLoadBalancerStats()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="40" y="2260" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--95" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--99" target="8GXi-stoHSAcCtSXBaf--100">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--96" value="选取服务节点后回调" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="8GXi-stoHSAcCtSXBaf--95">
<mxGeometry relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--97" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--99" target="8GXi-stoHSAcCtSXBaf--104">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--98" value="submit() 实现" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="8GXi-stoHSAcCtSXBaf--97">
<mxGeometry x="0.05" y="-4" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--99" value="LoadBalancerCommand.&lt;String&gt;builder()<br>.withLoadBalancer(loadBalancer)<br>.build().<b>submit</b>(new ServerOperation&lt;String&gt;() {...})<br>.toBlocking().<b>first</b>()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="280" y="1620" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--100" value="<div style="font-size: 9px;"><font style="font-size: 9px;">url = new URL("http://" + server.getHost() + ":" + server.getPort() + path);<br>HttpURLConnection conn = (HttpURLConnection) url.openConnection();</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">return Observable.just(conn.getResponseMessage());</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;" vertex="1" parent="1">
<mxGeometry x="760" y="1620" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--101" value="<div style="text-align: center;"><font color="#000000">com.netflix.loadbalancer.</font><b style="color: rgb(0, 0, 0); background-color: initial;">LoadBalancerCommand</b></div><hr style="font-size: 10px;" size="1"><font style="font-size: 10px;">每个对象表示一次负载均衡调用执行<br>选择Sever -&gt; 调用call(Server) -&gt; 调用ExecutionListener <br>(如果有的话) -&gt; call异常重试 -&gt; 提供反馈信息到LoadBalancerStats<br><br><span style="color: rgb(0, 0, 0); background-color: initial;">private final URI&nbsp; &nbsp; loadBalancerURI;</span><br><span style="background-color: initial; font-size: 10px;"><div style=""><div style="color: rgb(0, 0, 0);">private final Object loadBalancerKey;</div><div style="">//里面主要是LoadBalancer实例</div><div style="color: rgb(0, 0, 0);">private final LoadBalancerContext <b>loadBalancerContext</b>;</div><div style="color: rgb(0, 0, 0);">private final RetryHandler <b>retryHandler</b>;</div><div style="color: rgb(0, 0, 0);">private volatile ExecutionInfo executionInfo;</div><div style="">//如果没有手动指定server就为null, 通过selectServer()选取一个服务实例</div><div style="color: rgb(0, 0, 0);">private final Server <b>server</b>;</div><div style="">//监听Command执行生命周期:onExecutionStart()&nbsp;onStartWithServer()</div><div style="">//onExceptionWithServer()&nbsp;onExecutionSuccess()&nbsp;onExecutionFailed()</div><div style="color: rgb(0, 0, 0);">private final ExecutionContextListenerInvoker&lt;?, T&gt; <b>listenerInvoker</b>;</div></div></span></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fontColor=#007FFF;" vertex="1" parent="1">
<mxGeometry x="-1200" y="760" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--102" value="<font style="font-size: 10px;" color="#007fff">响应式回调,这里并没有异步调用</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="775" y="1680" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--103" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--104" target="8GXi-stoHSAcCtSXBaf--106">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--104" value="final ExecutionInfoContext context = new ExecutionInfoContext();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" vertex="1" parent="1">
<mxGeometry x="520" y="1700" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--105" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--106" target="8GXi-stoHSAcCtSXBaf--108">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--106" value="if (listenerInvoker != null) {<br>&nbsp; &nbsp; <b>listenerInvoker</b>.onExecutionStart();<br>}" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="520" y="1780" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--108" target="8GXi-stoHSAcCtSXBaf--112">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--108" value="<div>final int maxRetrysSame = retryHandler.getMaxRetriesOnSameServer();</div><div>final int maxRetrysNext = retryHandler.getMaxRetriesOnNextServer();</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="520" y="1860" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--109" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--112" target="8GXi-stoHSAcCtSXBaf--114">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--110" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--112" target="8GXi-stoHSAcCtSXBaf--116">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--111" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--112" target="8GXi-stoHSAcCtSXBaf--118">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--112" value="<font style="font-size: 9px;">Observable&lt;T&gt; <b>o</b> =&nbsp;(server == null ? <b>selectServer</b>() : Observable.just(server))<br>.<b>concatMap</b>(new Func1&lt;Server, Observable&lt;T&gt;&gt;() {...})</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="520" y="1940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--113" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--114" target="8GXi-stoHSAcCtSXBaf--124">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--114" value="<font size="1">selectServer()</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;verticalAlign=middle;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="760" y="1940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--115" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--116" target="8GXi-stoHSAcCtSXBaf--100">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--116" value="operation.call(server)<br><font color="#3333ff">核心是调用请求,另外还有一些请求次数记录、监听通知、状态记录等操作,略</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="760" y="2020" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--117" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--118" target="8GXi-stoHSAcCtSXBaf--120">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--118" value="<div>if (maxRetrysNext &gt; 0 &amp;&amp; server == null)&nbsp;</div><div>o = o.<b>retry</b>(retryPolicy(maxRetrysNext, false));</div><div><font color="#3333ff">通过RxJava接口设置重试策略</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="510" y="2100" width="220" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--119" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--120" target="8GXi-stoHSAcCtSXBaf--151">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--120" value="return o.<b>onErrorResumeNext</b>(new Func1&lt;Throwable, Observable&lt;T&gt;&gt;() {...});<br><font color="#3333ff">如果前面发生错误,会执行这里面的逻辑</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="520" y="2180" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--121" value="<font color="#007fff" style="font-size: 10px;">如果没有指定LoadBalancerCommand server<br>就通过selectServer() 选择一个</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="300" y="1950" width="220" height="40" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--122" value="<font style="font-size: 10px;" color="#007fff">ExecutionContextListenerInvoker <br>用于监听Command执行生命周期:onExecutionStart() <br>onStartWithServer()&nbsp;<span style="background-color: initial;">onExceptionWithServer() <br>onExecutionSuccess() onExecutionFailed()</span>&nbsp;</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="260" y="1775" width="260" height="70" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--123" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--124" target="8GXi-stoHSAcCtSXBaf--128">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--124" value="<font size="1">Server server = loadBalancerContext<br>.getServerFromLoadBalancer(<br>loadBalancerURI, loadBalancerKey);<br>...&nbsp;</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1000" y="1940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--125" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=diamondThin;endFill=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--126" target="8GXi-stoHSAcCtSXBaf--101">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--126" value="<div style="text-align: center;"><font color="#000000">com.netflix.loadbalancer.</font><b style="color: rgb(0, 0, 0); background-color: initial;">LoadBalancerContext</b></div><hr style="font-size: 10px;" size="1"><font style="font-size: 10px;">负载均衡器上下文,来自于&nbsp;LoadBalancerCommand$Builder<br><br><div style=""><font color="#000000"><span style="font-size: 10px;">protected String clientName = "default";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">protected String vipAddresses;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">protected int maxAutoRetriesNextServer = CommonClientConfigKey</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>.MaxAutoRetriesNextServer.defaultValue();</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">protected int maxAutoRetries = CommonClientConfigKey</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>.MaxAutoRetries.defaultValue();</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">protected RetryHandler defaultRetryHandler =&nbsp;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>new DefaultLoadBalancerRetryHandler();</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">protected boolean okToRetryOnAllOperations = CommonClientConfigKey</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;"><span style=""><span style="">&nbsp;&nbsp;&nbsp;&nbsp;</span></span>.OkToRetryOnAllOperations.defaultValue();</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">private ILoadBalancer <b>lb</b>;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">private volatile Timer tracer;</span></font></div></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fontColor=#007FFF;" vertex="1" parent="1">
<mxGeometry x="-1600" y="760" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--127" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--128" target="8GXi-stoHSAcCtSXBaf--131">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--128" value="<font size="1">Server svc = lb.chooseServer(loadBalancerKey);</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;verticalAlign=middle;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1241" y="1940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--129" value="BaseLoadBalancer" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1281" y="1910" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--130" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--131" target="8GXi-stoHSAcCtSXBaf--133">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--131" value="<div>if (counter == null) {</div><div>&nbsp; &nbsp; counter = createCounter();</div><div>}</div><div>counter.increment();</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="1480" y="1940" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--132" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--133" target="8GXi-stoHSAcCtSXBaf--135">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1700" y="2050" />
<mxPoint x="1700" y="1270" />
<mxPoint x="1221" y="1270" />
<mxPoint x="1221" y="525" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--133" value="return rule.choose(key);<br><font color="#007fff">具体参考各种负载均衡规则的实现</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;verticalAlign=middle;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="1480" y="2020" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--134" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--135" target="8GXi-stoHSAcCtSXBaf--138">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--135" value="<div style=""><font size="1"><b>choose</b>(Object key)</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1241" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--136" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--138" target="8GXi-stoHSAcCtSXBaf--140">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--137" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--138" target="8GXi-stoHSAcCtSXBaf--145">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1700" y="510" />
<mxPoint x="1700" y="650" />
<mxPoint x="1230" y="650" />
<mxPoint x="1230" y="1005" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--138" value="<div style="font-size: 9px;"><div>int count = 0;</div><div>Server server = <b>roundRobinRule</b>.choose(key);</div><div>while (count++ &lt;= 10) {</div><div>&nbsp; &nbsp; if (server != null &amp;&amp; <b>predicate</b>.apply(new PredicateKey(server))) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return server;</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; server = roundRobinRule.choose(key);</div><div>}</div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=7;" vertex="1" parent="1">
<mxGeometry x="1480" y="460" width="200" height="100" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--139" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--140" target="8GXi-stoHSAcCtSXBaf--142">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--140" value="<div style=""><font size="1">return super.choose(key);</font><br></div><div style=""><font size="1"><font color="#007fff">使用 PredicateBasedRule 选择Server</font><br></font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;arcSize=7;" vertex="1" parent="1">
<mxGeometry x="1480" y="581" width="200" height="59" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--141" value="<font style="font-size: 10px;"><font color="#007fff">即先使用RoundRobinRule选择一个Server, </font><br><span style="color: rgb(0, 127, 255);">然后使用服务可用性断言进行校验,校验失败重试(最多10次)</span><br><span style="color: rgb(0, 127, 255);">经过10次还是失败则使用 PredicateBasedRule 选择Server<br></span><font color="#3333ff"><b>之所以这么实现主要是因为服务不可用是小概率事件,异常的服务实例往往占据很小一部分<br>而直接对所有服务进行可用性校验是很耗费性能的事</b></font><br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1690" y="465" width="420" height="90" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--142" value="<div style=""><font size="1">ILoadBalancer lb = getLoadBalancer();</font><br></div><div style=""><font size="1">Optional&lt;Server&gt; server = getPredicate()<br>.chooseRoundRobinAfterFiltering(</font></div><div style=""><font size="1">lb.getAllServers(), key);<br></font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=7;" vertex="1" parent="1">
<mxGeometry x="1720" y="581" width="200" height="59" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--143" value="PredicateBasedRule" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1755" y="551" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--144" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="8GXi-stoHSAcCtSXBaf--145" target="8GXi-stoHSAcCtSXBaf--146">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--145" value="<div style=""><font size="1">choose(Object key)</font><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="1241" y="960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--146" value="<div style="">while循环(最多10次)从&nbsp;lb.getAllServers()</div><div style="">中用RoundRobin算法选择一个Server实例<br>如果&nbsp;server.<b>isAlive</b>() &amp;&amp; (server.<b>isReadyToServe</b>()) 就返回否则重试</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" vertex="1" parent="1">
<mxGeometry x="1480" y="960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--147" value="<font style="font-size: 10px;" color="#007fff">先对所有服务进行可用性校验,过滤出<br>合格的Server列表再用RoundRobin算法选择</font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1920" y="590.5" width="220" height="40" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--148" value="AvailabilityFilteringRule" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1505" y="430" width="150" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--149" value="RoundRobinRule" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1524" y="930" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--150" value="TODO" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
<mxGeometry x="1690" y="975" width="60" height="30" as="geometry" />
</mxCell>
<mxCell id="8GXi-stoHSAcCtSXBaf--151" value="只是额外封装些错误信息,通知监听器<br>listenerInvoker.onExecutionFailed(...)<br>最后&nbsp;return Observable.error(e);<br><font color="#3333ff">这部分不需要关注</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="760" y="2180" width="200" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>