這篇文章給大家介紹如何理解DependenciesBasedLoadBalancer,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
坊子網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站開發(fā)等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)2013年開創(chuàng)至今到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
本文主要研究一下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 MapruleCache = 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方法會根據(jù)ZookeeperDependency.getLoadBalancerType()進行chooseRuleForLoadBalancerType,這里分為了ROUND_ROBIN、RANDOM、STICKY三種
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 AtomicReferenceourInstance = 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 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列表,對于該列表沒有l(wèi)ocalOurInstance的,則更新本地引用為null;然后判斷l(xiāng)ocalOurInstance是否為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方法會根據(jù)ZookeeperDependency.getLoadBalancerType()進行chooseRuleForLoadBalancerType,這里分為了ROUND_ROBIN、RANDOM、STICKY三種
關(guān)于如何理解DependenciesBasedLoadBalancer就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。