SpringCloud Ribbon原理-3-restTemplate调用之负载均衡实现

1. 负载均衡器LoadBalancer获取

上一篇文章中org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient#execute(java.lang.String, org.springframework.cloud.client.loadbalancer.LoadBalancerRequest, java.lang.Object) 方法中有两个关键步骤:

	public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
			throws IOException {
    
    
		ILoadBalancer loadBalancer = getLoadBalancer(serviceId);   //  获取负载均衡器
		Server server = getServer(loadBalancer, hint);    // 根据负载均衡器获取到某一个具体的要调用的server
		if (server == null) {
    
    
			throw new IllegalStateException("No instances available for " + serviceId);
		}
		RibbonServer ribbonServer = new RibbonServer(serviceId, server,
				isSecure(server, serviceId),
				serverIntrospector(serviceId).getMetadata(server));

		return execute(serviceId, ribbonServer, request);
	}

ILoadBalancer loadBalancer = getLoadBalancer(serviceId); ,需要确定下这个ILoadBalancer 具体是哪一个实现,getLoadBalancer代码如下:
在这里插入图片描述
对this.clientFactory.getLoadBalancer(serviceId); 中的 getLoadBalancer执行 ctrl+ alt+B 操作:
在这里插入图片描述
找到getInstance方法的实现,可以看到它调用了父类NamedContextFactory 的getInstance
在这里插入图片描述

debug 得知这个LoadBalancer就是 ZoneAwareLoadBalancer :
在这里插入图片描述
在这里插入图片描述
进入父类的方法中:org.springframework.cloud.context.named.NamedContextFactory#getInstance(java.lang.String, java.lang.Class)
在这里插入图片描述
也就是说,文章开头的ILoadBalancer, 是通过spring应用上下文以getBean的方式获取的。

2. 请求目标服务器Server获取

**Server server = getServer(loadBalancer, hint);**  进入这个方法:

在这里插入图片描述
调用了一个chooseServer,实现是在之前确定的ZoneAwareLoadBalancer 中:
在这里插入图片描述
是在父类BaseLoadBalancer中实现的:
在这里插入图片描述
而父类中,却调用了一个rule.choose()方法,这里就涉及到了负载均衡策略的选择了。首先,这个rule是什么,如何确定的

2.1 ribbon负载均衡策略

通过debug, 得知使用的负载均衡策略是ZoneAvoidanceRule ,并且是一个复合断言
在这里插入图片描述
对IRule , ctrl +H 查看它的继承关系如下:
在这里插入图片描述
在这里插入图片描述
代码如下:
在这里插入图片描述
在这里插入图片描述
这里eligible不为空,那么会执行eligible.get(incrementAndGetModulo(eligible.size())) ,也就是轮询逻辑算法的实现:

private int incrementAndGetModulo(int modulo) {
    
    
        for (;;) {
    
    
            int current = nextIndex.get();
            int next = (current + 1) % modulo;
            if (nextIndex.compareAndSet(current, next) && current < modulo)
                return current;
        }
    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41300437/article/details/109273730
今日推荐