Ribbon负载均衡
负载均衡原理
springcloud底层利用Ribbon来实现的负载均衡。以Eureka为例,当发起一个请求的时候,Ribbon会将该请求拦截下来,然后根据请求的服务名去Eureka的服务端获取服务列表,然后根据负载均衡策略选择合适的服务进行访问。
接下来对源码进行追踪看RIbbon是如何实现负载均衡的
源码追踪
当在浏览器发起请求的时候,代码内部通过RestTemplate发起Http请求:http://userservice/user/1
双击shift搜索到LoadBalancerInterceptor
,在下图中位置打上断点,然后往下进行,会发现执行进入了LoadBalancerInterceptor
。
从图片可以看到这个intercept
方法拦截了用户的HttpRequest请求,然后进行了如下操作:
-
request.getURI()
从HttpRequest中获取到了该请求的URI -
originalUri.getHost()
从获取到的URI中获取到host,即服务名称。 -
this.loadBalancer.execute()
在该方法中处理服务名称和用户的请求。
如上图可知this.loadBalancer.execute
是LoadBalancerClient
类型,点击LoadBalancerClient
继续跟入:
按住Ctrl点击鼠标右键然后选择如图蓝色的实现类:
进去之后如图打上断点:
继续往下执行,代码会进到该方法,其中对63
和64
行代码解释如下:
-
getLoadBalancer(serviceId)
:根据服务id获取ILoadBalancer,而ILoadBalancer会拿着服务id去eureka中获取服务列表并保存起来。运行到63行后点击下图蓝色字样可以看到如下信息,其中LAPTOP-GLM61P9G
为主机名,相当于127.0.0.1
: -
getServer(loadBalancer)
:利用内置的负载均衡算法,从服务列表中选择一个。如下图可以看到选择了8081端口的服务:
放行再次访问会发现访问的端口会变成8082,故此实现了负载均衡。
getServer进行负载均衡:
接下来我们继续看getServer
这个方法是如何来做负载均衡的:
按住Ctrl点击getServer
方法跳转到该方法所在位置:
继续按住Ctrl点击chooseServer
跟入:
点击框中标志选择第一个点击进入:
可以看到跳转到了如下图中代码的位置,其中红框中的位置负责进行服务的选择:
按住Ctrl点击rule,跳转到定义rule的地方:
结合上面两张图片可以看到这里的rule默认值是一个RoundRobinRule
而RoundRobinRule
就是轮询的意思。
到此整个负载均衡的流程就清楚了。