《SpringCloud》笔记五:负载均衡——Ribbon组件(1)

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

所有课程的学习及相关资料都是源自b站黑马程序员 感谢黑马程序员给予我们新手的无私帮助,感谢!!! 黑马程序员-----yyds

@[toc]

一、什么是负载均衡

老规矩,看百度百科

负载均衡其意思就是分摊到多个操作单元上进行执行,例如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} 内看看(长按ctrl+鼠标左键

在这里插入图片描述 其实这个接口抽象了一个实现对客户端发起http请求的方法。 那我们再次回到它的实现类代码里面,我们继续往下看。 我们在如下位置打一个断点进行测试

在这里插入图片描述 我们以debug的模式重新启动我们关闭的那几个服务 再次来到浏览器里面,输入如下内容,回车

在这里插入图片描述 在断点处看到如下结果

在这里插入图片描述 我们发现服务器并没有立即响应数据给浏览器,而是对浏览器发起的http请求进行了拦截操作。那 g e t U R I 函数 \color{red}{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();} ,再走一步。

在这里插入图片描述

获取的是主机名,也就是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()} 我们将鼠标悬停在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} 的实例属性。中文名就是负载均衡客户端。 我们继续跟入 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} ,名叫:动态服务列表负载均衡器

在这里插入图片描述

在这里插入图片描述

那么很明显,服务列表已经成功的被拉取到了,所以刚才的操作就是向eureka获取的所需的服务列表!

在这里插入图片描述

那接下来要干嘛,当然是完成负载均衡操作了,那getServer函数就很关键了,因为这直接影响到负载均衡是怎么选取合适的服务实例。 我们跟进去这个函数。

在这里插入图片描述 我们发现它调用了一个chooseServer函数,可能就是选取合适的server,我们继续跟入这个函数内部。

在这里插入图片描述

现在有一个非常尴尬的问题,因为我userservice只开了一个服务实例,所以进不去这个条件内部,不要紧我们发现它将继续调用父类的chooseServer函数,我们继续跟进去。

在这里插入图片描述

在这里插入图片描述 我们继续往下,现在有一个很关键的东西来了,叫 r u l e \color{red}{rule} (规则),我们都知道负载均衡是有一些算法的,那么这个rule是不是帮助我们选择一个默认的负载均衡算法用的呢?继续跟入。

可以看出,这个 r u l e \color{red}{rule} 是一个 I R u l e \color{red}{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} ,这个规则是含义是什么后续会说,而且相对重要。 那么到现在为止,我们已经知道了负载均衡的算法规则是怎么样子的了。 是不是有种恍然大悟的感觉。

后续内容下期笔记更新(求三连,谢谢) 共勉

猜你喜欢

转载自juejin.im/post/7085630671028224013