侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

聊聊DependenciesBasedLoadBalancer

2022-09-24 星期六 / 0 评论 / 0 点赞 / 82 阅读 / 8468 字

序本文主要研究一下DependenciesBasedLoadBalancerDependenciesBasedLoadBalancerspring-cloud-zookeeper-discovery-

本文主要研究一下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三种

doc

.
.

广告 广告

评论区