如何理解DependenciesBasedLoadBalancer

这篇文章给大家介绍如何理解DependenciesBasedLoadBalancer,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

坊子网站制作公司哪家好,找创新互联!从网页设计、网站建设、微信开发、APP开发、响应式网站开发等网站项目制作,到程序开发,运营维护。创新互联2013年开创至今到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联

本文主要研究一下DependenciesBasedLoadBalancer

DependenciesBasedLoadBalancer

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/dependency/DependenciesBasedLoadBalancer.java

public class DependenciesBasedLoadBalancer extends DynamicServerListLoadBalancer {

	private static final Log log = LogFactory.getLog(DependenciesBasedLoadBalancer.class);

	private final Map<String, IRule> ruleCache = new ConcurrentHashMap<>();

	private final ZookeeperDependencies zookeeperDependencies;

	public DependenciesBasedLoadBalancer(ZookeeperDependencies zookeeperDependencies,
			ServerList<?> serverList, IClientConfig config, IPing iPing) {
		super(config);
		this.zookeeperDependencies = zookeeperDependencies;
		setServersList(serverList.getInitialListOfServers());
		setPing(iPing);
		setServerListImpl(serverList);
	}

	@Override
	public Server chooseServer(Object key) {
		String keyAsString;
		if ("default".equals(key)) { // this is the default hint, use name instead
			keyAsString = getName();
		}
		else {
			keyAsString = (String) key;
		}
		ZookeeperDependency dependency = this.zookeeperDependencies
				.getDependencyForAlias(keyAsString);
		log.debug(String.format("Current dependencies are [%s]",
				this.zookeeperDependencies));
		if (dependency == null) {
			log.debug(String.format(
					"No dependency found for alias [%s] - will use the default rule which is [%s]",
					keyAsString, this.rule));
			return this.rule.choose(key);
		}
		cacheEntryIfMissing(keyAsString, dependency);
		log.debug(String.format(
				"Will try to retrieve dependency for key [%s]. Current cache contents [%s]",
				keyAsString, this.ruleCache));
		updateListOfServers();
		return this.ruleCache.get(keyAsString).choose(key);
	}

	private void cacheEntryIfMissing(String keyAsString, ZookeeperDependency dependency) {
		if (!this.ruleCache.containsKey(keyAsString)) {
			log.debug(String.format("Cache doesn't contain entry for [%s]", keyAsString));
			this.ruleCache.put(keyAsString,
					chooseRuleForLoadBalancerType(dependency.getLoadBalancerType()));
		}
	}

	private IRule chooseRuleForLoadBalancerType(LoadBalancerType type) {
		switch (type) {
		case ROUND_ROBIN:
			return getRoundRobinRule();
		case RANDOM:
			return getRandomRule();
		case STICKY:
			return getStickyRule();
		default:
			throw new IllegalArgumentException("Unknown load balancer type " + type);
		}
	}

	private RoundRobinRule getRoundRobinRule() {
		return new RoundRobinRule(this);
	}

	private IRule getRandomRule() {
		RandomRule randomRule = new RandomRule();
		randomRule.setLoadBalancer(this);
		return randomRule;
	}

	private IRule getStickyRule() {
		StickyRule stickyRule = new StickyRule(getRoundRobinRule());
		stickyRule.setLoadBalancer(this);
		return stickyRule;
	}

}
  • DependenciesBasedLoadBalancer继承了com.netflix.loadbalancer.DynamicServerListLoadBalancer

  • 其chooseServer方法会使用zookeeperDependencies.getDependencyForAlias来跟进key获取ZookeeperDependency,如果dependency为null则直接使用rule.choose(key),不为null则进行chahe,然后更新server列表,最后通过ruleCache.get(keyAsString).choose(key)返回

  • cacheEntryIfMissing方法会根据ZookeeperDependency.getLoadBalancerType()进行chooseRuleForLoadBalancerType,这里分为了ROUND_ROBIN、RANDOM、STICKY三种

StickyRule

spring-cloud-zookeeper-discovery-2.1.2.RELEASE-sources.jar!/org/springframework/cloud/zookeeper/discovery/dependency/StickyRule.java

public class StickyRule extends AbstractLoadBalancerRule {

	private static final Log log = LogFactory.getLog(StickyRule.class);

	private final IRule masterStrategy;

	private final AtomicReference<Server> ourInstance = new AtomicReference<>(null);

	private final AtomicInteger instanceNumber = new AtomicInteger(-1);

	public StickyRule(IRule masterStrategy) {
		this.masterStrategy = masterStrategy;
	}

	@Override
	public void initWithNiwsConfig(IClientConfig iClientConfig) {

	}

	@Override
	public Server choose(Object key) {
		final List<Server> instances = getLoadBalancer().getServerList(true);
		log.debug(String.format("Instances taken from load balancer [%s]", instances));
		Server localOurInstance = this.ourInstance.get();
		log.debug(String.format("Current saved instance [%s]", localOurInstance));
		if (!instances.contains(localOurInstance)) {
			this.ourInstance.compareAndSet(localOurInstance, null);
		}
		if (this.ourInstance.get() == null) {
			Server instance = this.masterStrategy.choose(key);
			if (this.ourInstance.compareAndSet(null, instance)) {
				this.instanceNumber.incrementAndGet();
			}
		}
		return this.ourInstance.get();
	}

	/**
	 * Each time a new instance is picked, an internal counter is incremented. This way
	 * you can track when/if the instance changes. The instance can change when the
	 * selected instance is not in the current list of instances returned by the instance
	 * provider
	 * @return instance number
	 */
	public int getInstanceNumber() {
		return this.instanceNumber.get();
	}

}
  • StickyRule继承了com.netflix.loadbalancer.AbstractLoadBalancerRule;其choose方法首先通过getLoadBalancer().getServerList(true)获取server列表,对于该列表没有localOurInstance的,则更新本地引用为null;然后判断localOurInstance是否为null,为null的话则使用masterStrategy.choose(key)进行选择然后更新;最后返回ourInstance.get()

小结

  • DependenciesBasedLoadBalancer继承了com.netflix.loadbalancer.DynamicServerListLoadBalancer

  • 其chooseServer方法会使用zookeeperDependencies.getDependencyForAlias来跟进key获取ZookeeperDependency,如果dependency为null则直接使用rule.choose(key),不为null则进行chahe,然后更新server列表,最后通过ruleCache.get(keyAsString).choose(key)返回

  • cacheEntryIfMissing方法会根据ZookeeperDependency.getLoadBalancerType()进行chooseRuleForLoadBalancerType,这里分为了ROUND_ROBIN、RANDOM、STICKY三种

关于如何理解DependenciesBasedLoadBalancer就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

新闻标题:如何理解DependenciesBasedLoadBalancer
文章网址:https://www.cdcxhl.com/article22/ghcdjc.html

成都网站建设公司_创新互联,为您提供软件开发面包屑导航营销型网站建设静态网站企业网站制作搜索引擎优化

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

营销型网站建设