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