所有课程的学习及相关资料都是源自b站黑马程序员
感谢黑马程序员给予我们新手的无私帮助,感谢!!!
黑马程序员-----yyds
一、什么是负载均衡
老规矩,看百度百科
负载均衡其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
其实,用通俗的话来说,让服务流量均衡化,举个例子:
如果一个银行只有一个窗口,有好多百姓等着办理自己的业务,那么这个窗口就将变得十分繁忙,而且对于排队的人来说,延迟阻塞的情况是十分严重的,而负载均衡就是做到多个服务窗口,让排队的人不局限于一个窗口办理业务,这样不仅解决了一个窗口繁忙的服务,而且可以扩大工作量,俗称增大吞吐量。
二、负载均衡原理
如果我们想要了解Spring里面负载均衡的具体原理,那我们就必须深入源码学习,这可能是大家认为最痛苦的地方(虽然都是认识的东西,但是组合起来就不认识)
我们开始进入源码的学习(这一步是大家以后必走的!!!)
我们进入到order-service的项目的OrderApplication.java里面
按下 ctrl + shift + n
切换到classes,输入如下数据进行搜索
可以看到,我们搜索的这个LoadBalancerInterceptor继承了ClientHttpRequestInterceptor这个接口,这个接口也叫
客
户
端
请
求
拦
截
器
\color{red}{客户端请求拦截器}
客户端请求拦截器
那这个接口是干什么的呢?
我们点进
C
l
i
e
n
t
H
t
t
p
R
e
q
u
e
s
t
I
n
t
e
r
c
e
p
t
o
r
\color{red}{ClientHttpRequestInterceptor}
ClientHttpRequestInterceptor 内看看(长按ctrl+鼠标左键)
其实这个接口抽象了一个实现对客户端发起http请求的方法。
那我们再次回到它的实现类代码里面,我们继续往下看。
我们在如下位置打一个断点进行测试
我们以debug的模式重新启动我们关闭的那几个服务
再次来到浏览器里面,输入如下内容,回车
在断点处看到如下结果
我们发现服务器并没有立即响应数据给浏览器,而是对浏览器发起的http请求进行了拦截操作。那
g
e
t
U
R
I
函
数
\color{red}{getURI函数}
getURI函数就是获取请求的地址 ,不信我们就再走一步看看
诺,结果很明确,收到的就是userservice请求,而且请求的参数(也就是userId为1)。那程序拿到这个无法访问的地址要干什么呢,我们看第二个函数 o r i g i n a l U r i . g e t H o s t ( ) ; \color{red}{originalUri.getHost();} originalUri.getHost(); ,再走一步。
获取的是主机名,也就是userservice,我们猜想他接下来想通过这个主机名去向eureka拉取相关的服务实例列表,以得到相关的IP和端口号。我们继续往下走,一直走到
t
h
i
s
.
l
o
a
d
B
a
l
a
n
c
e
r
.
e
x
e
c
u
t
e
(
)
\color{red}{this.loadBalancer.execute()}
this.loadBalancer.execute()
我们将鼠标悬停在loadBalancer上
它是
R
i
b
b
o
n
L
o
a
d
B
a
l
a
n
c
e
r
C
l
i
e
n
t
\color{red}{RibbonLoadBalancerClient}
RibbonLoadBalancerClient 的实例属性。中文名就是负载均衡客户端。
我们继续跟入 execute方法里面
通过上面函数传进来的参数,也就是“userservice“,交给了getLoadBalancer函数。那么执行完这个函数我们能得到一个ILoadBalancer对象,这个对象所属的类是
D
y
n
a
m
i
c
S
e
r
v
e
r
L
i
s
t
L
o
a
d
B
a
l
a
n
c
e
r
\color{red}{DynamicServerListLoadBalancer}
DynamicServerListLoadBalancer,名叫:动态服务列表负载均衡器
那么很明显,服务列表已经成功的被拉取到了,所以刚才的操作就是向eureka获取的所需的服务列表!
那接下来要干嘛,当然是完成负载均衡操作了,那getServer函数就很关键了,因为这直接影响到负载均衡是怎么选取合适的服务实例。
我们跟进去这个函数。
我们发现它调用了一个chooseServer函数,可能就是选取合适的server,我们继续跟入这个函数内部。
现在有一个非常尴尬的问题,因为我userservice只开了一个服务实例,所以进不去这个条件内部,不要紧我们发现它将继续调用父类的chooseServer函数,我们继续跟进去。
我们继续往下,现在有一个很关键的东西来了,叫
r
u
l
e
\color{red}{rule}
rule(规则),我们都知道负载均衡是有一些算法的,那么这个rule是不是帮助我们选择一个默认的负载均衡算法用的呢?继续跟入。
可以看出,这个 r u l e \color{red}{rule} rule是一个 I R u l e \color{red}{IRule} IRule类型,emm以I命名开头的不出意外就是一个接口,那接口肯定就有实现类,那我们找找它的实现类。
IDEA可以通过ctrl+h快捷键查看IRule的实现类。
可以看出这个IRule有很多的实现类,再看看这些实现类,那么现在答案已经渐渐浮出水面了。
那你肯定在这个时候不禁好奇,默认的负载均算法规则是什么呢
就是下面这个
默认的叫
Z
o
n
e
A
v
o
i
d
a
n
c
e
R
u
l
e
\color{red}{ZoneAvoidanceRule}
ZoneAvoidanceRule,这个规则是含义是什么后续会说,而且相对重要。
那么到现在为止,我们已经知道了负载均衡的算法规则是怎么样子的了。
是不是有种恍然大悟的感觉。
后续内容下期笔记更新(求三连,谢谢)
共勉