-
Notifications
You must be signed in to change notification settings - Fork 1
/
spring-cloud-loadbalancer.drawio
1213 lines (1213 loc) · 199 KB
/
spring-cloud-loadbalancer.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
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<mxfile host="Electron" modified="2024-05-02T13:58:23.229Z" 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="dFgQc1dhGNc9LEhdesDi" version="21.6.5" type="device" pages="3">
<diagram id="f3Fi9e5t7PhujOKiYEsx" name="SpringCloudLoadBalancer">
<mxGraphModel dx="3915" dy="842" grid="1" gridSize="10" guides="0" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" background="none" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="KydxWmPEN0qJnf4pflOT-1" value="<p style="line-height: 1"></p><h1><font style="font-size: 20px">Spring Cloud LoadBalancer 工作原理</font><font style="font-size: 16px">&nbsp;</font><font style="font-size: 10px">(v3.1.5)&nbsp;</font></h1><div style="font-size: 10px"><font style="font-size: 10px">这里研究 LoadBalancer 结合 Nacos 的负载均衡实现原理</font></div><div style="font-size: 10px"><font style="font-size: 10px">所有测试DEMO,参考 SpringBoot-Labs/netflix-ribbon。</font></div><p style="font-size: 10px"><font style="font-size: 10px">前提:</font></p><p style="font-size: 10px"></p><ul style="font-size: 10px"><li style="font-size: 10px">Spring Cloud NamedContextFactory 机制(参考对应原理流程图,主要是为Specification创建独立的隔离的子应用上下文)</li></ul><div>说明:<br><div><br></div></div><p style="font-size: 10px"></p><p></p>" style="text;html=1;strokeColor=none;fillColor=none;spacing=5;spacingTop=-20;whiteSpace=wrap;overflow=hidden;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="10" y="20" width="590" height="140" as="geometry" />
</mxCell>
<mxCell id="9Nb5X1CC6daOf7xSNShJ-1" value="<font style="font-size: 10px;">需要重点关注的一些原理:<br><ul><li><font style="font-size: 10px;">Spring Cloud LoadBalancer 是如何为不同的服务创建配置不同的客户端的?<br></font><font color="#007fff">主要归功于 NamedContextFactory 机制</font></li><li><font style="font-size: 10px;">服务节点列表发生动态变更,SpringCloud如何及时监测到并更新缓存列表?</font></li></ul></font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="600" y="20" width="640" height="140" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-6" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-1" target="khGB8-cCiWg7Y-Ce-5PI-5" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-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;fontSize=10;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-1" target="khGB8-cCiWg7Y-Ce-5PI-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-11" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;fontSize=10;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-1" target="khGB8-cCiWg7Y-Ce-5PI-10" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-1" value="自动配置阶段" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-22" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-5" target="khGB8-cCiWg7Y-Ce-5PI-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-5" value="spring-cloud-starter-alibaba-nacos-discovery<br>spring.factories" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-20" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-7" target="khGB8-cCiWg7Y-Ce-5PI-19" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-7" value="spring-cloud-starter-loadbalancer<br>spring.factories" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-17" 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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-10" target="khGB8-cCiWg7Y-Ce-5PI-12" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-18" 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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-10" target="khGB8-cCiWg7Y-Ce-5PI-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-24" 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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-10" target="khGB8-cCiWg7Y-Ce-5PI-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-29" 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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-10" target="khGB8-cCiWg7Y-Ce-5PI-15" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-10" value="请求处理流程<br><font color="#007fff">省略Spring MVC WebFlux&nbsp; 处理流程<br>直接看Controller层负载均衡处理</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-104" style="edgeStyle=orthogonalEdgeStyle;rounded=0;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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-12" target="uEqFnHDyktXJyKcs36Fb-103" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-12" value="@LoadBalanced WebClient.Builder<br><font color="#007fff">在BeanPostProcessor中为WebClient.Builder添加了一个过滤器</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="1840" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-14" target="uEqFnHDyktXJyKcs36Fb-106" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-14" value="ReactorLoadBalancerExchangeFilterFunction<br>WebClient.Builder" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="1960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-83" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-15" target="uEqFnHDyktXJyKcs36Fb-82" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-96" 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;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-15" target="uEqFnHDyktXJyKcs36Fb-95" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-15" value="@LoadBalanced RestTemplate<br><font color="#007fff">本质是在RestTemplate拦截器中注册了一个<b>负载均衡拦截LoadBalancerInterceptor</b>,<br>猜测还以为是创建了个动态代理</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="1320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-19" value="<div><b>LoadBalancerAutoConfiguration</b></div><div><b>BlockingLoadBalancerClientAutoConfiguration</b></div><div>LoadBalancerCacheAutoConfiguration</div><div>OAuth2LoadBalancerClientAutoConfiguration</div><div>LoadBalancerStatsAutoConfiguration</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;arcSize=8;" parent="1" vertex="1">
<mxGeometry x="500" y="350" width="240" height="80" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-21" value="<div>NacosDiscoveryAutoConfiguration</div><div>NacosDiscoveryEndpointAutoConfiguration</div><div>NacosServiceRegistryAutoConfiguration</div><div>NacosDiscoveryClientConfiguration</div><div>NacosReactiveDiscoveryClientConfiguration</div><div>NacosConfigServerAutoConfiguration</div><div><b>LoadBalancerNacosAutoConfiguration</b></div><div>NacosServiceAutoConfiguration</div><div>UtilIPv6AutoConfiguration</div><div><b>NacosLoadBalancerClientConfiguration</b><br></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;arcSize=7;" parent="1" vertex="1">
<mxGeometry x="500" y="170" width="240" height="120" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-23" target="khGB8-cCiWg7Y-Ce-5PI-25" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-23" value="LoadBalancerClient&nbsp;RestTemplate<br><font color="#007fff">这里默认注入的是&nbsp;BlockingLoadBalancerClient</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-25" target="khGB8-cCiWg7Y-Ce-5PI-27" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-7" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-25" target="iAYe1x8H37XBPk3sPTiQ-6" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-25" value="ServiceInstance instance = <b>loadBalancerClient</b>.choose("demo-provider")" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-81" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-27" target="uEqFnHDyktXJyKcs36Fb-80" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-27" value="根据 ServiceInstance (包括host port 等信息)创建真正的请求URL targetUrl" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-84" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-32" target="khGB8-cCiWg7Y-Ce-5PI-25" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="860" y="390" />
<mxPoint x="860" y="770" />
<mxPoint x="620" y="770" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-32" value="<div><span style="background-color: initial;">BlockingLoadBalancerClient</span><br></div><div><font color="#007fff">依赖Bean LoadBalancerClientFactory</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="880" y="360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-33" target="iAYe1x8H37XBPk3sPTiQ-3" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-33" value="LoadBalancerClientFactory<br><font color="#007fff">继承 NamedContextFactory&lt;<br>LoadBalancerClientSpecification&gt;</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="880" y="280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-5" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.009;entryY=0.091;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#d5e8d4;strokeColor=default;shadow=0;" parent="1" source="khGB8-cCiWg7Y-Ce-5PI-37" target="khGB8-cCiWg7Y-Ce-5PI-45" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-37" value="LoadBalancerClientsProperties<br><font color="#007fff">spring.cloud.loadbalancer 前缀的配置属性,内部还有一些子属性类</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="880" y="200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-45" value="<div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff"><b>约定的默认配置:</b></font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">properties = {<b>LoadBalancerClientsProperties</b>@6009}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>clients</b> = {HashMap@6030}&nbsp; size = 0</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>healthCheck</b> = {LoadBalancerProperties$HealthCheck@6031}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; initialDelay = {Duration@6037} "PT0S"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; interval = {Duration@6038} "PT25S"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; refetchInstancesInterval = {Duration@6039} "PT25S"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; path = {LinkedCaseInsensitiveMap@6040}&nbsp; size = 0</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; port = null</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; refetchInstances = false</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; repeatHealthCheck = true</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>hint</b> = {LinkedCaseInsensitiveMap@6032}&nbsp; size = 0</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>hintHeaderName</b> = "X-SC-LB-Hint"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>retry</b> = {LoadBalancerProperties$Retry@6034}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; enabled = true</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; retryOnAllOperations = false</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; maxRetriesOnSameServiceInstance = 0</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; maxRetriesOnNextServiceInstance = 1</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; retryableStatusCodes = {HashSet@7051}&nbsp; size = 0</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; backoff = {LoadBalancerProperties$Retry$Backoff@7052}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>stickySession</b> = {LoadBalancerProperties$StickySession@6035}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; instanceIdCookieName = "sc-lb-instance-id"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; addServiceInstanceCookie = false</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>useRawStatusCodeInResponseData</b> = false</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp;<b>xForwarded</b> = {LoadBalancerProperties$XForwarded@6036}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;" color="#007fff">&nbsp; enabled = false</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;labelBorderColor=default;" parent="1" vertex="1">
<mxGeometry x="1440" y="200" width="320" height="330" as="geometry" />
</mxCell>
<mxCell id="khGB8-cCiWg7Y-Ce-5PI-47" value="<font style="font-size: 10px;">创建的重要Bean</font>" style="shape=singleArrow;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="760" y="280" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-1" value="<div style="text-align: center;"><font style=""><font color="#000000"><b>BlockingLoadBalancerClient&nbsp;</b></font></font><span style="background-color: initial;">implements LoadBalancerClient</span></div><hr style="font-size: 10px;" size="1"><font style="font-size: 10px;"><font color="#007fff">这个并不是实际的客户端实现,从其成员字段可以看到它其实是 <b>NamedContextFactory</b>, <b>要查询某个服务<br>专属的子应用上下文还是需要通过这个Bean</b><br></font><br><span style="background-color: initial;"><div style="font-size: 10px;"><font color="#007fff">//实际类型是 LoadBalancerClientFactory,继承 NamedContextFactory&lt;<span style="background-color: initial;">LoadBalancerClientSpecification&gt;</span></font></div><div style=""><font color="#000000"><span style="font-size: 10px;">private final ReactiveLoadBalancer.Factory&lt;ServiceInstance&gt; <b>loadBalancerClientFactory</b>;</span></font><br></div></span></font>" style="verticalAlign=top;align=left;overflow=fill;fontSize=12;fontFamily=Helvetica;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-520" y="200" width="480" height="120" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-3" value="<font style="font-size: 9px;"><font style="font-size: 9px;">super(</font><b style="font-size: 9px;">LoadBalancerClientConfiguration</b><font style="font-size: 9px;">.class, "loadbalancer", "loadbalancer.client.name");</font><br><font style="font-size: 9px;" color="#007fff">隔离的子应用上下文中都会加载配置类</font><span style="font-size: 9px; border-color: var(--border-color);"><font style="font-size: 9px;" color="#007fff"><b>LoadBalancerClientConfiguration</b>,另外关注<br></font></span><font style="font-size: 9px;" color="#007fff"><b>LoadBalancerClientSpecification </b>定义的隔离的Bean</font><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1100" y="280" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-10" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-6" target="iAYe1x8H37XBPk3sPTiQ-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-21" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-6" target="iAYe1x8H37XBPk3sPTiQ-20" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-6" value="ReactiveLoadBalancer&lt;ServiceInstance&gt; loadBalancer = this.loadBalancerClientFactory<br>.<b>getInstance</b>(serviceId);<br><font color="#007fff">// 1</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="760" y="801" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-8" value="BlockingLoadBalancerClient" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="775" y="769" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-3" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0;exitDx=0;exitDy=0;fillColor=#d5e8d4;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-9" target="uEqFnHDyktXJyKcs36Fb-2" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1240" y="790" />
<mxPoint x="1240" y="645" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-9" value="return (ReactiveLoadBalancer)this<br>.<b>getInstance</b>(serviceId, ReactorServiceInstanceLoadBalancer.class);<br><font color="#007fff">从serviceId的子应用上下文获取&nbsp;ReactorServiceInstanceLoadBalancer Bean实例<br>默认获取的是 <b>RoundRobinLoadBalancer</b><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="980" y="790" width="240" height="81" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-11" value="<font style="font-size: 10px;">这里可以看到是以 serviceId (即服务名) 为name,&nbsp;隔离子应用上下文的,<br>不过 ReactorServiceInstanceLoadBalancer 实例<br>是通过 <b>NamedContextFactory</b> defautlConfigType(<b style="border-color: var(--border-color); font-size: 9px; text-align: center;">LoadBalancerClientConfiguration</b>)&nbsp;在子应用上下文&nbsp;<b>refresh</b>() 时加载的<br>即&nbsp;LoadBalancerClientConfiguration<br></font>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="1220" y="790" width="560" height="70" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-12" target="iAYe1x8H37XBPk3sPTiQ-31" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-12" value="RoundRobinLoadBalancer<br><font color="#007fff">Bean名:reactorServiceInstanceLoadBalancer</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="880" y="440" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-13" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">RandomLoadBalancer</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-250" y="520" width="200" height="33" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-14" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><i style="font-size: 10px;">&lt;&lt;interface&gt;&gt;</i><br style="font-size: 10px;"><b style="font-size: 10px;">ReactorLoadBalancer<t style="font-size: 10px;"></t></b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-384" y="360" width="227" height="39" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-15" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><i style="font-size: 10px;">&lt;&lt;interface&gt;&gt;</i><br style="font-size: 10px;"><b style="font-size: 10px;">ReactorServiceInstanceLoadBalancer</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-426" y="441" width="310" height="39" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-16" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">RoundRobinLoadBalancer</b></p><hr style="font-size: 10px;"><font color="#007fff">&nbsp;轮询负载均衡器</font><br><br>final AtomicInteger position;<div>final String serviceId;</div><div><font color="#007fff">//ObjectProvider 其实就是用于获取ServiceInstanceListSupplier Bean实例的</font></div><div>ObjectProvider&lt;ServiceInstanceListSupplier&gt; serviceInstanceListSupplierProvider;</div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-680" y="520" width="386" height="120" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-17" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-13" target="iAYe1x8H37XBPk3sPTiQ-15" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-152" y="510" />
<mxPoint x="-271" y="510" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-18" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-15" target="iAYe1x8H37XBPk3sPTiQ-14" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-19" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-16" target="iAYe1x8H37XBPk3sPTiQ-15" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-487" y="510" />
<mxPoint x="-271" y="510" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-20" target="iAYe1x8H37XBPk3sPTiQ-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-20" target="iAYe1x8H37XBPk3sPTiQ-26" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-20" value="Response&lt;ServiceInstance&gt; loadBalancerResponse = (Response)<br>Mono.from(loadBalancer.<b>choose</b>(request))<br>.<b>block</b>();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="900" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-22" value="<ol><li><span style="background-color: initial;">通过NamedContextFactory机制获取serviceId对应的ReactiveLoadBalancer Bean实例,默认是</span>RoundRobinLoadBalancer<br>(即从某服务独立的子应用上下文获取其响应式<b>负载均衡器</b>)</li><li>loadBalancer先获取ServiceInstanceListSupplier Bean 然后用此Supplier获取服务实例列表,最后根据负载均衡规则选取一个服务实例并返回<br>(即负载均衡器包含一个懒加载获取ServiceInstanceListSupplier Bean的 <b>ObjectProvider</b>, 通过它获取 Supplier Bean 后,然后获取服务实例列表,最终会从 Nacos NacosReactiveDiscoveryClient 读取服务实例列表)<br></li><li>执行负载均衡器中定义的负载均衡规则,从服务实例列表中选择一个实例</li><li>通过服务实例的地址信息创建真正的请求URL, 然后借助RestTemplate执行请求</li></ol>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=top;whiteSpace=wrap;rounded=0;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="240" y="860" width="360" height="180" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-23" value="return loadBalancerResponse == null ? null : (ServiceInstance)loadBalancerResponse<br>.getServer();" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="760" y="1060" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-30" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-26" target="iAYe1x8H37XBPk3sPTiQ-29" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-34" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-26" target="iAYe1x8H37XBPk3sPTiQ-33" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-26" value="<font style="font-size: 9px;">ServiceInstanceListSupplier supplier = (ServiceInstanceListSupplier)this.<br><b>serviceInstanceListSupplierProvider</b>.getIfAvailable(<br>NoopServiceInstanceListSupplier::new);</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="980" y="900" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-28" value="RoundRobinLoadBalancer" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1020" y="880" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-44" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-29" target="iAYe1x8H37XBPk3sPTiQ-43" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-37" 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;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-29" target="uEqFnHDyktXJyKcs36Fb-4" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1230" y="1010" />
<mxPoint x="1230" y="1250" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-29" value="<div><font size="1">return <b>supplier</b>.<b>get</b>(request).<b>next</b>()</font><span style="font-size: x-small; background-color: initial;">.map(</span></div><div><span style="font-size: x-small; background-color: initial;">(serviceInstances) -&gt; {</span></div><div><font size="1">&nbsp; &nbsp; return this.<b>processInstanceResponse</b>(supplier, serviceInstances);</font></div><div><font size="1">});</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="980" y="980" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-31" value="new RoundRobinLoadBalancer(<br>loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1100" y="440" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-36" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-33" target="iAYe1x8H37XBPk3sPTiQ-35" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-33" value="return this.delegate()<br>.getIfAvailable(defaultSupplier);<br><font color="#007fff">获取&nbsp;ServiceInstanceListSupplier Bean实例<br>为空则通过defaultSupplier 创建<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1240" y="900" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-35" target="iAYe1x8H37XBPk3sPTiQ-38" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-35" value="this.provider = this.clientFactory.getProvider(this.name, this.type);<br><font color="#007fff">首次执行provider为null, 创建provider后存到provider</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1480" y="900" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-37" value="ClientFactoryObjectProvider" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1250" y="878" width="170" height="30" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-38" target="iAYe1x8H37XBPk3sPTiQ-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-38" value="<div>AnnotationConfigApplicationContext context = this.getContext(name);</div><div>return context.<b>getBeanProvider</b>(type);</div><div><font color="#007fff">获取ServiceInstanceListSupplier的 ObjectProvider</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1720" y="900" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-40" value="NamedContextFactory" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="1750" y="878" width="140" height="30" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-41" value="<div>resolveBean()</div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="1960" y="900" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-34" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="iAYe1x8H37XBPk3sPTiQ-43" target="uEqFnHDyktXJyKcs36Fb-33" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="iAYe1x8H37XBPk3sPTiQ-43" value="supplier.get(request)<br><font color="#007fff">ServiceInstanceListSupplier是<b>装饰器模式</b>组织的,会依次执行每一层get()<br>// 2<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1240" y="980" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-68" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-1" target="uEqFnHDyktXJyKcs36Fb-67" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-1" value="DiscoveryClientServiceInstanceListSupplier<br><font color="#007fff">Bean名:reactorServiceInstanceLoadBalancer</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="880" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-2" value="<div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">this.<b>clientFactory</b> = {LoadBalancerClientFactory@9255}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;properties = {LoadBalancerClientsProperties@9278}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;propertySourceName = "loadbalancer"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;propertyName = "loadbalancer.client.name"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;<b>contexts</b> = {ConcurrentHashMap@9281}&nbsp; size = 1</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; "demo-provider" -&gt; {AnnotationConfigApplicationContext@9277}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;key = "demo-provider"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp;value = {<b>AnnotationConfigApplicationContext</b>@9277}</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; ...</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; <b>beanFactory</b> = {DefaultListableBeanFactory@10536}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp;...</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp;<b>singletonObjects</b> = {ConcurrentHashMap@10617}&nbsp; size = 22</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration$ReactiveSupportConfiguration" -&gt; {LoadBalancerClientConfiguration$ReactiveSupportConfiguration@10530}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.annotation.internalConfigurationAnnotationProcessor" -&gt; {ConfigurationClassPostProcessor@10905}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "propertySourcesPlaceholderConfigurer" -&gt; {PropertySourcesPlaceholderConfigurer@10906}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "applicationStartup" -&gt; {DefaultApplicationStartup@10574}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "autoConfigurationReport" -&gt; {ConditionEvaluationReport@10909}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.event.internalEventListenerFactory" -&gt; {DefaultEventListenerFactory@10910}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "systemEnvironment" -&gt; {Collections$UnmodifiableMap@10912}&nbsp; size = 50</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.event.internalEventListenerProcessor" -&gt; {EventListenerMethodProcessor@10913}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "propertyPlaceholderAutoConfiguration" -&gt; {PropertyPlaceholderAutoConfiguration@10914}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "loadBalancerClientConfiguration" -&gt; {LoadBalancerClientConfiguration@10915}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "lifecycleProcessor" -&gt; {DefaultLifecycleProcessor@10833}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.annotation.internalAutowiredAnnotationProcessor" -&gt; {AutowiredAnnotationBeanPostProcessor@10917}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry" -&gt; {ConfigurationClassParser$ImportStack@10919}&nbsp; size = 0</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "applicationEventMulticaster" -&gt; {SimpleApplicationEventMulticaster@10573}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "environment" -&gt; {StandardEnvironment@10566}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.context.annotation.internalCommonAnnotationProcessor" -&gt; {CommonAnnotationBeanPostProcessor@10922}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "<b>reactorServiceInstanceLoadBalancer</b>" -&gt; {RoundRobinLoadBalancer@10802}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "<b>discoveryClientServiceInstanceListSupplier</b>" -&gt; {CachingServiceInstanceListSupplier@10523}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "systemProperties" -&gt; {Properties@10924}&nbsp; size = 70</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "xForwarderHeadersTransformer" -&gt; {XForwardedHeadersTransformer@10925}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "messageSource" -&gt; {DelegatingMessageSource@10572} "Empty MessageSource"</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; "org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration$BlockingSupportConfiguration" -&gt; {LoadBalancerClientConfiguration$BlockingSupportConfiguration@10927}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp; &nbsp; &nbsp; ...</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;configurations = {ConcurrentHashMap@9282}&nbsp; size = 2</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;parent = {AnnotationConfigServletWebServerApplicationContext@9283}&nbsp;</font></div><div style="font-size: 10px;"><font color="#007fff" style="font-size: 10px;">&nbsp;defaultConfigType = {Class@9284} "class org.springframework.cloud.loadbalancer.annotation.<b>LoadBalancerClientConfiguration</b>"</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;labelBorderColor=default;" parent="1" vertex="1">
<mxGeometry x="1760" y="410" width="910" height="470" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-64" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-4" target="uEqFnHDyktXJyKcs36Fb-63" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-4" value="processInstanceResponse(supplier, serviceInstances)<br><font color="#007fff">next() 等待服务实例列表返回后,根据负载均衡规则选择一个实例回&nbsp;DefaultResponse<br>// 3<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1240" y="1220" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-5" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">CachingServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">&nbsp;private final <b>Flux</b>&lt;List&lt;ServiceInstance&gt;&gt; <br><span style="white-space: pre;">	</span><b>serviceInstances</b>;" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1140" y="962" width="250" height="58" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-6" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">DelegatingServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">&nbsp;protected final ServiceInstanceListSupplier delegate;" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-1040" y="870" width="256" height="44" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-71" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;fillColor=#d5e8d4;strokeColor=default;shape=link;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-7" target="uEqFnHDyktXJyKcs36Fb-70" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-7" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">DiscoveryClientServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-748.5" y="881" width="260" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-8" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">HealthCheckServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1380" y="962" width="227" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-9" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">HintBasedServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-870" y="962" width="220" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-10" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">NoopServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-470" y="881" width="180" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-11" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">RequestBasedStickySessionServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1710" y="962" width="300" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-12" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">RetryAwareServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1970" y="962" width="221" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-13" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">SameInstancePreferenceServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-330" y="962" width="280" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-14" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><i style="font-size: 10px;">&lt;&lt;interface&gt;&gt;</i><br style="font-size: 10px;"><b style="font-size: 10px;">SelectedInstanceCallback</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-200" y="875" width="160" height="39" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-15" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><i style="font-size: 10px;">&lt;&lt;interface&gt;&gt;</i><br style="font-size: 10px;"><b style="font-size: 10px;">ServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="-740" y="800" width="243" height="39" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-16" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">ZonePreferenceServiceInstanceListSupplier</b></p><hr style="font-size: 10px;">" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-610" y="962" width="243" height="33" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-17" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-5" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-18" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-6" target="uEqFnHDyktXJyKcs36Fb-15" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-912" y="860" />
<mxPoint x="-618" y="860" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-19" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-7" target="uEqFnHDyktXJyKcs36Fb-15" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-20" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-8" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1266" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-21" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-9" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-760" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-22" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-10" target="uEqFnHDyktXJyKcs36Fb-15" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-380" y="860" />
<mxPoint x="-618" y="860" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-23" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-11" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1560" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-24" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-12" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-1859" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-25" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.250;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-13" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-260" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-26" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=1;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.750;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-13" target="uEqFnHDyktXJyKcs36Fb-14" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-120" y="920" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-27" value="" style="html=1;rounded=1;edgeStyle=orthogonalEdgeStyle;dashed=0;startArrow=none;endArrow=block;endSize=12;strokeColor=default;exitX=0.500;exitY=0.002;exitDx=0;exitDy=0;entryX=0.500;entryY=1.002;entryDx=0;entryDy=0;fontSize=10;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-16" target="uEqFnHDyktXJyKcs36Fb-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points">
<mxPoint x="-488" y="937" />
<mxPoint x="-912" y="937" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-28" value="<font style="font-size: 10px;" color="#007fff">如果启用健康检查、粘性会话、提示等功能<br>会加载多个ServiceInstanceListSupplier 实现<br>组织模式是<b>装饰器模式</b></font>" style="text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-1270" y="860" width="220" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-29" value="<font color="#000000" style="font-size: 10px;">Spring Cloud LoadBalancer + Nacos 不添加任何配置的话,默认就是下面这种<br><span style="font-size: 10px;">如果开启多种功能,会在中间插入其他的ServiceInstanceListSupplier实现</span><br></font><div style="font-size: 10px;"><font style="font-size: 10px;">this = {<b>CachingServiceInstanceListSupplier</b>@10523}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;serviceInstances = {FluxDefer@10932} "FluxDefer"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp;<b>delegate</b> = {<b>DiscoveryClientServiceInstanceListSupplier</b>@10524}&nbsp;</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; timeout = {Duration@10934} "PT30S"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; serviceId = "demo-provider"</font></div><div style="font-size: 10px;"><font style="font-size: 10px;">&nbsp; serviceInstances = {FluxDefer@10935} "FluxDefer"</font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fontColor=#007FFF;" parent="1" vertex="1">
<mxGeometry x="-920" y="1040" width="370" height="110" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-46" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-33" target="uEqFnHDyktXJyKcs36Fb-45" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-33" value="<b>CachingServiceInstanceListSupplier</b>#get()<br><font color="#007fff">定义先从缓存中取服务实例列表,缓存为空则交给下一级(<b>delegate</b>) ServiceInstanceListSupplier get()</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1480" y="980" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-59" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-35" target="uEqFnHDyktXJyKcs36Fb-57" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-35" value="<font style="font-size: 9px;"><b>DiscoveryClientServiceInstanceListSupplier</b>#<br>get()<br><font color="#007fff">定义从服务发现服务中获取服务实例列表</font><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1480" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-53" 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;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-38" target="uEqFnHDyktXJyKcs36Fb-35" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1700" y="1090" />
<mxPoint x="1700" y="1130" />
<mxPoint x="1460" y="1130" />
<mxPoint x="1460" y="1170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-38" value="<font size="1">中间根据配置可能有其他ServiceInstanceListSupplier<br>不过这些&nbsp;</font>Supplier 不是共存的,有些和 Cache Supplier 也不共存<font size="1"><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1480" y="1060" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-45" target="uEqFnHDyktXJyKcs36Fb-47" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-45" value="return serviceInstances;<br><font color="#007fff">是Flux&lt;List&lt;ServiceInstance&gt;&gt; 类型,即数据发布者</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1720" y="980" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-51" 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;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-47" target="uEqFnHDyktXJyKcs36Fb-38" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="2180" y="1010" />
<mxPoint x="2180" y="1050" />
<mxPoint x="1460" y="1050" />
<mxPoint x="1460" y="1090" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-54" value="onCacheMissResume 内部逻辑" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="uEqFnHDyktXJyKcs36Fb-51" vertex="1" connectable="0">
<mxGeometry x="-0.6906" y="2" relative="1" as="geometry">
<mxPoint x="-31" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-47" value="serviceInstances = <b>CacheFlux</b>.<b>lookup</b>(key -&gt; {...}, delegate.getServiceId())<br>.<b>onCacheMissResume</b>(...).<b>andWriteWith</b>(...)<br><font color="#007fff">CacheFlux属于reactor-extra的逻辑,不深入了</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1960" y="980" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-50" value="<font style="font-size: 10px;" color="#007fff"><font style="font-size: 10px;">lookup: 先从缓存查询,<br>onCacheMissResume: 查询为空执行,即从下一个ServiceInstanceListSupplier#get() 获取,<br>andWriteWith: 获取成功再写入缓存<br>参考测试:&nbsp;</font>CacheFluxLoadBalancerTest#testMockLoadBalancerCacheFlux()</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="2180" y="980" width="420" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-60" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-57" target="uEqFnHDyktXJyKcs36Fb-58" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-57" value="return serviceInstances;<br><font color="#007fff">是Flux&lt;List&lt;ServiceInstance&gt;&gt; 类型,即数据发布者</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1720" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-62" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-58" target="uEqFnHDyktXJyKcs36Fb-61" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-58" value="serviceInstances = Flux.defer(() -&gt; {...})<br>.onErrorResume(...)" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1960" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-75" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-61" target="uEqFnHDyktXJyKcs36Fb-74" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-61" value="<b>delegate</b>.getInstances(serviceId)<br>.collectList().flux()<br><font color="#007fff">这里delegate 就是配置类中创建的</font><br><font color="#007fff">&nbsp;NacosReactiveDiscoveryClient</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="2200" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-66" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-63" target="uEqFnHDyktXJyKcs36Fb-65" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-63" value="Response&lt;ServiceInstance&gt; serviceInstanceResponse = <b>getInstanceResponse</b>(serviceInstances);<br><font color="#007fff">此方法中定义负载均衡规则实现</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1480" y="1220" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-65" value="<div>int pos = this.position.incrementAndGet() &amp; Integer.MAX_VALUE;</div><div>ServiceInstance instance = instances.get(pos % instances.size());<span style=""></span></div><div><font color="#007fff">RoundRobin 主要实现是这两行代码</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="1720" y="1220" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-67" value="return <b>ServiceInstanceListSupplier</b>.builder()<br>.withDiscoveryClient().withCaching()<br>.build(context);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="1120" y="520" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-69" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>ServiceInstanceListSupplierBuilder</b><br></p><hr style="font-size: 10px;"><font color="#007fff">&nbsp;业务中真正的ServiceInstanceListSupplier 是经过层层装饰的对象,是使用这个<br>&nbsp;Builder类构建起来的</font><br><br><font color="#007fff">//实际用于获取服务实例列表的 Supplier 的创建 Function, 比如DiscoveryClientServiceInstanceListSupplier<br></font><div>private Creator baseCreator;<span style=""><span style="white-space: pre;">&nbsp;&nbsp;</span></span></div><div><span style=""><span style="white-space: pre;"><font color="#007fff">//缓存Supplier 的创建 Function </font></span></span></div><div>private DelegateCreator cachingCreator;</div><div><font color="#007fff">//其他过滤服务实例的 Supplier 的创建 Function, 这些 Supplier 逻辑不是共存的</font></div><div>private final List&lt;DelegateCreator&gt; creators = new ArrayList&lt;&gt;();</div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-520" y="1040" width="480" height="140" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-70" value="<p style="margin: 4px 0px 0px; text-align: center;"><b>DiscoveryClientServiceInstanceListSupplier</b><br></p><hr style="font-size: 10px;"><font color="#007fff">&nbsp;</font><br><div><div>private Duration timeout = Duration.ofSeconds(30);</div><div>private final String serviceId;</div><div><font color="#007fff">// serviceInstances 是个Flux发布器,内部通过 delegate.getInstances(serviceId)&nbsp;</font></div><div><font color="#007fff">获取服务列表,而 <b>delegate 是配置类中创建的 ReactiveDiscoveryClient Bean实例</b></font></div><div>private final Flux&lt;List&lt;ServiceInstance&gt;&gt; <b>serviceInstances</b>;</div></div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1200" y="720" width="400" height="120" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-72" value="NacosReactiveDiscoveryClient<br><font color="#007fff">Bean名:nacosReactiveDiscoveryClient</font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="880" y="600" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-73" value="<font color="#007fff" style="font-size: 10px;">太多了,梳理后面逻辑的时候<br>遇到要注入Bean再回来找</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="730" y="340" width="150" height="40" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-77" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-74" target="uEqFnHDyktXJyKcs36Fb-76" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-74" value="<font style="font-size: 9px;">return Mono.justOrEmpty(serviceId)<br>.flatMapMany(this.<b>loadInstancesFromNacos</b>())<br>.subscribeOn(Schedulers.boundedElastic());</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="2440" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-79" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-76" target="uEqFnHDyktXJyKcs36Fb-78" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-76" value="<font size="1">serviceDiscovery.<b>getInstances</b>(serviceId)</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="2680" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-78" value="<font size="1">String group = this.discoveryProperties.getGroup();<br><b>nacosServiceManager</b>.getNamingService()<br></font>.<b>selectInstances</b>(serviceId, group, true);<br><font color="#007fff">这里回去看下Nacos源码流程</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="2920" y="1140" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-80" value="String response = restTemplateWithoutLB.<b>getForObject</b>(<br>targetUrl, String.class);<br><font color="#007fff">// 4 执行 RestTemplate 常规请求</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="520" y="1220" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-82" target="uEqFnHDyktXJyKcs36Fb-85" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-89" 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;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-82" target="uEqFnHDyktXJyKcs36Fb-87" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-93" 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;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-82" target="uEqFnHDyktXJyKcs36Fb-91" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-94" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.439;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-82" target="uEqFnHDyktXJyKcs36Fb-90" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-82" value="@LoadBalanced 相关处理逻辑<br><font color="#007fff">参考LoadBalancerAutoConfiguration</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="1320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-85" value="<div style="font-size: 9px;"><font style="font-size: 9px;">@LoadBalanced</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">@Autowired(required = false)</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">private List&lt;RestTemplate&gt; restTemplates = Collections.emptyList();</font></div><div style="font-size: 9px;"><font color="#007fff" style="font-size: 9px;">注入所有注释有@LoadBalanced的RestTemplate Bean</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;" parent="1" vertex="1">
<mxGeometry x="760" y="1320" width="240" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-92" 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;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-87" target="uEqFnHDyktXJyKcs36Fb-90" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="1170" y="1680" />
<mxPoint x="1170" y="1590" />
<mxPoint x="750" y="1590" />
<mxPoint x="750" y="1555" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-87" value="<div style="font-size: 9px;"><div style=""><div>@Bean</div><div>public <b>SmartInitializingSingleton</b> loadBalancedRestTemplateInitializerDeprecated(</div><div>&nbsp; &nbsp; &nbsp; &nbsp; final <b>ObjectProvider</b>&lt;List&lt;RestTemplateCustomizer&gt;&gt; <b>restTemplateCustomizers</b>) {</div><div>&nbsp; &nbsp; return () -&gt; restTemplateCustomizers.ifAvailable(customizers -&gt; {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.<b>restTemplates</b>) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (RestTemplateCustomizer customizer : customizers) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <b>customizer</b>.customize(restTemplate);&nbsp;<font color="#007fff"> //即执行&nbsp;LoadBalancerInterceptor 的注册</font></div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; });</div><div>}</div><div><font color="#007fff">创建 SmartInitializingSingleton Bean, 会在所有单例Bean初始化完成后调用&nbsp;afterSingletonsInstantiated() 即 这里的 lambda 表达式</font></div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=3;" parent="1" vertex="1">
<mxGeometry x="760" y="1600" width="400" height="160" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-90" value="<div style="font-size: 9px;"><div style="">@Bean</div><div style=""><span style="">@ConditionalOnMissingBean</span></div><div style="">public <b>RestTemplateCustomizer</b> restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) {</div><div style=""><span style="">&nbsp; &nbsp; return restTemplate -&gt; {</span></div><div style=""><font color="#007fff">&nbsp; &nbsp; &nbsp; &nbsp; 里面将 <b>loadBalancerInterceptor</b> 添加到 restTemplate 的拦截器链中</font></div><div style=""><span style="">&nbsp; &nbsp; };</span></div><div style=""><span style="">}</span></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=8;" parent="1" vertex="1">
<mxGeometry x="760" y="1480" width="400" height="100" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-91" value="<div style="font-size: 8px;"><div style=""><div>@Bean</div><div>public LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; LoadBalancerRequestFactory requestFactory) {</div><div>&nbsp; &nbsp; return new <b>LoadBalancerInterceptor</b>(<b>loadBalancerClient</b>, requestFactory);</div><div>}</div><div><font style="font-size: 8px;" color="#007fff">// 这里的 loadBalancerClient 和 上面的是同一个Bean</font></div></div></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=9;" parent="1" vertex="1">
<mxGeometry x="760" y="1400" width="400" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-95" value="<font style="font-size: 10px;">RestTemplate 经过&nbsp;loadBalancerInterceptor<br>loadBalancerClient 处理后URL就转换成可以访问的URL了<br><font style="font-size: 10px;" color="#007fff">拦截器参考RestTemplate 源码流程图</font></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="1400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-97" value="LoadBalancerAutoConfiguration" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="790" y="1288" width="190" height="30" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-99" value="<font style="font-size: 10px;">借助 SmartInitializingSingleton 机制</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="280" y="1380" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-100" value="<font style="font-size: 10px;">借助 BeanPostProcessor 机制</font>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="280" y="1900" width="200" height="30" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-101" value="<div style="font-size: 9px;"><font style="font-size: 9px;">@Override</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">public Object <b>postProcessBeforeInitialization</b>(Object bean, String beanName) throws BeansException {</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; if (bean instanceof <b>WebClient.Builder</b>) {</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; &nbsp; &nbsp; if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) {</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return bean;</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; &nbsp; &nbsp; ((WebClient.Builder) bean).<b>filter</b>(exchangeFilterFunction);</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; }</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">&nbsp; &nbsp; return bean;</font></div><div style="font-size: 9px;"><font style="font-size: 9px;">}</font></div><div style="font-size: 9px;"><font color="#007fff" style="font-size: 9px;">即为所有注释有 @LoadBalanced 的&nbsp;WebClient.Builder 注册&nbsp;DeferringLoadBalancerExchangeFilterFunction</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=left;arcSize=2;" parent="1" vertex="1">
<mxGeometry x="760" y="1800" width="400" height="140" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-105" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=default;shadow=0;" parent="1" source="uEqFnHDyktXJyKcs36Fb-103" target="uEqFnHDyktXJyKcs36Fb-101" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-103" value="LoadBalancerWebClientBuilder<br>BeanPostProcessor" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="1840" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="uEqFnHDyktXJyKcs36Fb-106" value="WebClient.builder().filter(lbFunction).build()<br>.get().uri(...).retrieve()<br>.bodyToMono(...)<br><font color="#007fff">也是注册过滤器的方式,和上面相同</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="1960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-3" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-1" target="hy-jY-Vdd2qQ_RdFIRII-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-1" value="ServiceInstanceListSupplierBuilder&nbsp;<br>Bean 实例化原理<br><font color="#007fff">研究这个流程主要是为了自定义Supplier<br>这个Bean用了装饰器模式<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="2080" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-2" target="hy-jY-Vdd2qQ_RdFIRII-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-2" value="<b>LoadBalancerClientConfiguration</b>#<br>discoveryClientServiceInstanceListSupplier(<br>ConfigurableApplicationContext context))" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="2080" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-4" value="<font style="font-size: 9px;">return <b>ServiceInstanceListSupplier</b>.builder()<br>.withDiscoveryClient().withCaching()<br>.build(context);<br></font><font color="#007fff">通过withXxx() 方法装配功能, Supplier初始化原理较简单略</font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="520" y="2080" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-6" value="DiscoveryClientServiceInstanceListSupplier 是&nbsp;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-500" y="800" width="270" height="30" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-10" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeColor=default;shadow=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-8" target="hy-jY-Vdd2qQ_RdFIRII-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-13" 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;strokeColor=default;shadow=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-8" target="hy-jY-Vdd2qQ_RdFIRII-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-8" value="@LoadBalancerClient &amp;<br>@LoadBalancerClients 原理<br><font color="#007fff">其实本质就是<b>@Import</b>,源码搜索到右边两个应用场景<br></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="2180" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-9" value="<font size="1">DiscoveryLoadBalancerConfiguration<br>中用于创建 HasFeatures Bean<br><font color="#007fff">HasFeatures 机制用于 Actuator 中查看引入用了哪些功能的,暂略</font><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="2180" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-11" target="hy-jY-Vdd2qQ_RdFIRII-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-11" value="<font style=""><b style="font-size: 9px;">LoadBalancerClientConfigurationRegistrar</b><font size="1"> implements </font><b style="font-size: 9px;">ImportBeanDefinitionRegistrar</b><br><font style="" color="#007fff"><font size="1">实现了ImportBeanDefinitionRegistrar</font><br><font size="1">接口,就是用于注册BeanDefinition的</font></font><br></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="280" y="2260" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-14" value="<font size="1"><span style="font-weight: normal;">registry.registerBeanDefinition(...)</span></font>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="760" y="2260" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-16" value="<font style="font-size: 10px;"><font color="#007fff">这两个注解都注释了@Import<br><span style="">@Import(LoadBalancerClientConfigurationRegistrar.class)<br></span>@Import 注解处理原理参考 Spring流程图</font><br></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-40" y="2240" width="280" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-18" value="注意子应用上下文(Bean容器)维护在这个Bean里<br>调试时经常需要查看子应用上下文验证一些猜想或查看效果,<br>就从这个Bean进去<br><font color="#007fff"><br></font><div><font color="#007fff">loadBalancerClient = {BlockingLoadBalancerClient@9228}&nbsp;</font></div><div><font color="#007fff">&nbsp;<b>loadBalancerClientFactory</b> = {LoadBalancerClientFactory@9226}&nbsp;</font></div><div><font color="#007fff">&nbsp; properties = {LoadBalancerClientsProperties@9586}&nbsp;</font></div><div><font color="#007fff">&nbsp; propertySourceName = "loadbalancer"</font></div><div><font color="#007fff">&nbsp; propertyName = "loadbalancer.client.name"</font></div><div><font color="#007fff">&nbsp; <b>contexts</b> = {ConcurrentHashMap@9589}&nbsp; size = 1</font></div><div><font color="#007fff">&nbsp; &nbsp;"demo-provider" -&gt; {<b>AnnotationConfigApplicationContext</b>@9225}&nbsp;</font></div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="-920" y="195" width="400" height="170" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-20" value="<div style="font-size: 11px;"><font color="#ea6b66" style="font-size: 11px;">这里发现 @LoadBalancerClient &amp;&nbsp;<span style="background-color: initial;">@LoadBalancerClients 引入的配置类定义的Bean <br>并不会被父应用上下文加载,什么原因?测试参考 name 和&nbsp;</span>anotherName 这两个Bean</font></div><div style="font-size: 11px;"><font color="#ea6b66"><font style="font-size: 11px;">结合之前的Spring的流程图看&nbsp;</font>beanFactory.preInstantiateSingletons() 这一步确实没有 anotherName</font></div><div style="font-size: 11px;"><font color="#ea6b66" style="font-size: 11px;"><span style="background-color: initial;">TODO&nbsp;</span><span style="background-color: initial;">LoadBalancerClientConfigurationRegistrar 处理原理</span></font></div>" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="970" y="2260" width="510" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="hy-jY-Vdd2qQ_RdFIRII-21" target="hy-jY-Vdd2qQ_RdFIRII-14" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-21" value="<font size="1"><span style="font-weight: normal;">TODO</span></font>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fontStyle=1;fillColor=#f8cecc;strokeColor=#b85450;" parent="1" vertex="1">
<mxGeometry x="520" y="2260" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="hy-jY-Vdd2qQ_RdFIRII-24" value="<p style="margin: 4px 0px 0px; text-align: center; font-size: 10px;"><b style="font-size: 10px;">NacosLoadBalancer</b></p><hr style="font-size: 10px;"><font color="#007fff">&nbsp;Nacos实现的负载均衡器,使用<b>随机权重</b>算法,支持<b>总是连接同集群同IP类型服务实例</b></font><br><br><div>private final String <b>serviceId</b>;</div><div>private ObjectProvider&lt;ServiceInstanceListSupplier&gt; <b>serviceInstanceListSupplierProvider</b>;</div><div>private final NacosDiscoveryProperties <b>nacosDiscoveryProperties</b>;</div><div>private static final String IPV4_REGEX = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";</div><div>private static final String IPV6_KEY = "IPv6";</div><div>public static String <b>ipv6</b>;</div><div>@Autowired</div><div>private InetIPv6Utils <b>inetIPv6Utils</b>;</div>" style="verticalAlign=top;align=left;overflow=fill;fontSize=10;fontFamily=Helvetica;html=1;rounded=0;shadow=0;comic=0;labelBackgroundColor=none;strokeWidth=1;" parent="1" vertex="1">
<mxGeometry x="-1240" y="520" width="519" height="160" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="sthaRJRf7krDnvooZX53" name="Ribbon">
<mxGraphModel dx="3088" dy="879" 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="WeO6OLhi-FBfppIhu5CC-1" value="<b>URLConnectionLoadBalancerExample</b><br>使用LoadBalancerCommand通过固定Server列表的负载均衡器和HttpURLConnection发送请求的示例。" style="text;html=1;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="40" y="20" width="480" height="50" as="geometry" />
</mxCell>
<mxCell id="WeO6OLhi-FBfppIhu5CC-5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="WeO6OLhi-FBfppIhu5CC-3" target="WeO6OLhi-FBfppIhu5CC-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="WeO6OLhi-FBfppIhu5CC-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;" parent="1" vertex="1">
<mxGeometry x="40" y="80" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-3" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="WeO6OLhi-FBfppIhu5CC-4" target="dFHeEVBBE8L6X1gG-yMv-2" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-95" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="WeO6OLhi-FBfppIhu5CC-4" target="dFHeEVBBE8L6X1gG-yMv-94" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="WeO6OLhi-FBfppIhu5CC-4" value="URLConnectionLoadBalancer <b>urlLoadBalancer</b> = new URLConnectionLoadBalancer(servers);<br>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="40" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-1" 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;" parent="1" vertex="1">
<mxGeometry x="-320" y="80" width="280" height="240" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-11" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-2" target="dFHeEVBBE8L6X1gG-yMv-9" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-12" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-2" target="dFHeEVBBE8L6X1gG-yMv-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-2" value="loadBalancer = LoadBalancerBuilder.newBuilder()<br>.<b>buildFixedServerListLoadBalancer</b>(<br>serverList);" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="280" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-4" target="dFHeEVBBE8L6X1gG-yMv-30" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-42" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-4" target="dFHeEVBBE8L6X1gG-yMv-41" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-4" 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;" parent="1" vertex="1">
<mxGeometry x="520" y="400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-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;">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;" parent="1" vertex="1">
<mxGeometry x="-720" y="80" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-17" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-9" target="dFHeEVBBE8L6X1gG-yMv-16" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-9" 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;" parent="1" vertex="1">
<mxGeometry x="520" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-10" value="LoadBalancerBuilder" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
<mxGeometry x="555" y="130" width="130" height="30" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-13" 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;" parent="1" vertex="1">
<mxGeometry x="1241" y="320" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-22" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-16" target="dFHeEVBBE8L6X1gG-yMv-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-25" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-16" target="dFHeEVBBE8L6X1gG-yMv-23" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-16" 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;" parent="1" vertex="1">
<mxGeometry x="760" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-18" 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;" parent="1" vertex="1">
<mxGeometry x="1440.5" y="160" width="490" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-20" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;endArrow=diamondThin;endFill=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-19" target="dFHeEVBBE8L6X1gG-yMv-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-19" 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;" parent="1" vertex="1">
<mxGeometry x="-1120" y="80" width="360" height="240" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-27" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-21" target="dFHeEVBBE8L6X1gG-yMv-26" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-21" value="<b>ArchaiusClientConfigFactory</b>#<br>newConfig()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1000" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-29" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-23" target="dFHeEVBBE8L6X1gG-yMv-28" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-23" value="<b>DefaultClientConfigFactory</b>#<br>newConfig()" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;" parent="1" vertex="1">
<mxGeometry x="1000" y="240" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-26" 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;" parent="1" vertex="1">
<mxGeometry x="1241" y="160" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-28" value="<b>DefaultClientConfigImpl</b><br>implements IClientConfig" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;fillColor=#dae8fc;strokeColor=#6c8ebf;align=center;" parent="1" vertex="1">
<mxGeometry x="1240.5" y="240" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-33" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-30" target="dFHeEVBBE8L6X1gG-yMv-32" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-35" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-30" target="dFHeEVBBE8L6X1gG-yMv-34" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-30" 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;" parent="1" vertex="1">
<mxGeometry x="760" y="400" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-32" 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;" parent="1" vertex="1">
<mxGeometry x="990" y="400" width="220" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-40" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-34" target="dFHeEVBBE8L6X1gG-yMv-36" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-34" 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;" parent="1" vertex="1">
<mxGeometry x="760" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dtkDTw0i2Apqsin4ytUc-30" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-36" target="dtkDTw0i2Apqsin4ytUc-29" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-36" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="480" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-38" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="560" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-44" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;align=center;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-41" target="dFHeEVBBE8L6X1gG-yMv-43" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-92" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-41" target="dFHeEVBBE8L6X1gG-yMv-91" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-41" 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;" parent="1" vertex="1">
<mxGeometry x="520" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" vertex="1">
<mxGeometry x="520" y="1360" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-45" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="640" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-47" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="720" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-48" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="800" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-49" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="880" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dtkDTw0i2Apqsin4ytUc-41" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-50" target="dtkDTw0i2Apqsin4ytUc-40" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-50" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="960" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-51" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="1040" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-52" 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;" parent="1" vertex="1">
<mxGeometry x="1000" y="1120" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-53" value="<div style=""><font size="1">NacosRule</font></div>" style="rounded=1;whiteSpace=wrap;html=1;fontSize=10;align=center;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1">
<mxGeometry x="1000" y="1200" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-54" value="" style="shape=curlyBracket;whiteSpace=wrap;html=1;rounded=1;labelPosition=left;verticalLabelPosition=middle;align=right;verticalAlign=middle;" parent="1" vertex="1">
<mxGeometry x="980" y="480" width="10" height="700" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-55" 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;" parent="1" vertex="1">
<mxGeometry x="880" y="810" width="110" height="40" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-57" 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;" parent="1" vertex="1">
<mxGeometry x="-665" y="441" width="235" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-58" 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;" parent="1" vertex="1">
<mxGeometry x="-954" y="684" width="214" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-59" 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;" parent="1" vertex="1">
<mxGeometry x="-842" y="620" width="174" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-60" 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;" parent="1" vertex="1">
<mxGeometry x="-1006" y="522" width="310" height="58" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-61" 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;" parent="1" vertex="1">
<mxGeometry x="-590" y="360" width="85" height="39" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-62" 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;" parent="1" vertex="1">
<mxGeometry x="-1052" y="620" width="190" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-63" 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;" parent="1" vertex="1">
<mxGeometry x="-537" y="522" width="140" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-64" 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;" parent="1" vertex="1">
<mxGeometry x="-556" y="603" width="248" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-65" 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;" parent="1" vertex="1">
<mxGeometry x="-676" y="522" width="119" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-66" 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;" parent="1" vertex="1">
<mxGeometry x="-377" y="522" width="168" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-67" 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;" parent="1" vertex="1">
<mxGeometry x="-288" y="603" width="248" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-68" 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;" parent="1" vertex="1">
<mxGeometry x="-1162" y="684" width="188" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-69" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-57" target="dFHeEVBBE8L6X1gG-yMv-61" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-58" target="dFHeEVBBE8L6X1gG-yMv-62" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-59" target="dFHeEVBBE8L6X1gG-yMv-60" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-60" target="dFHeEVBBE8L6X1gG-yMv-57" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-62" target="dFHeEVBBE8L6X1gG-yMv-60" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-63" target="dFHeEVBBE8L6X1gG-yMv-57" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-64" target="dFHeEVBBE8L6X1gG-yMv-66" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-65" target="dFHeEVBBE8L6X1gG-yMv-57" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-66" target="dFHeEVBBE8L6X1gG-yMv-57" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-78" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-67" target="dFHeEVBBE8L6X1gG-yMv-66" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-79" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-68" target="dFHeEVBBE8L6X1gG-yMv-62" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-80" 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;" parent="1" vertex="1">
<mxGeometry x="-466" y="762" width="204" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-81" 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;" parent="1" vertex="1">
<mxGeometry x="-570" y="841" width="530" height="379" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-82" 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;" parent="1" vertex="1">
<mxGeometry x="-456.5" y="1240" width="303" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-83" 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;" parent="1" vertex="1">
<mxGeometry x="-438" y="681" width="149" height="39" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-84" 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;" parent="1" vertex="1">
<mxGeometry x="-800" y="840" width="185" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-85" 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;" parent="1" vertex="1">
<mxGeometry x="-430" y="1310" width="250" height="33" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-86" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-80" target="dFHeEVBBE8L6X1gG-yMv-83" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-81" target="dFHeEVBBE8L6X1gG-yMv-80" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-88" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-82" target="dFHeEVBBE8L6X1gG-yMv-81" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-89" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-84" target="dFHeEVBBE8L6X1gG-yMv-80" edge="1">
<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="dFHeEVBBE8L6X1gG-yMv-90" 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;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-85" target="dFHeEVBBE8L6X1gG-yMv-82" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<Array as="points" />
<mxPoint x="-305" y="1330" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-91" 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;" parent="1" vertex="1">
<mxGeometry x="760" y="1280" width="200" height="60" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-93" 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;" parent="1" vertex="1">
<mxGeometry x="740" y="1360" width="770" height="250" as="geometry" />
</mxCell>
<mxCell id="dFHeEVBBE8L6X1gG-yMv-97" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="dFHeEVBBE8L6X1gG-yMv-94" target="dFHeEVBBE8L6X1gG-yMv-96" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>