摘要:當(dāng)為空時(shí),會(huì)使用線性輪詢策略,當(dāng)有時(shí),會(huì)通過遍歷負(fù)載均衡器中維護(hù)的所有服務(wù)實(shí)例,會(huì)過濾掉故障的實(shí)例,并找出并發(fā)請(qǐng)求數(shù)最小的一個(gè)。
客戶端負(fù)載均衡Spring Cloud Ribbon
?Spring Cloud Ribbon是一個(gè)基于HTTP和TCP的客戶端負(fù)載均衡工具,基于Netflix Ribbon實(shí)現(xiàn)。
目錄客戶端負(fù)載均衡
源碼分析
負(fù)載均衡器
負(fù)載均衡策略(本文重點(diǎn))
配置詳解
自動(dòng)化配置
負(fù)載均衡器?負(fù)載均衡器相關(guān)內(nèi)容見上一篇文章
負(fù)載均衡策略 AbstractLoadBalancerRule?負(fù)載均衡策略的抽象類,在該抽象類中定義了負(fù)載均衡器ILoadBalancer對(duì)象,該對(duì)象能夠在具體實(shí)現(xiàn)選擇服務(wù)策略時(shí),獲取到一些負(fù)載均衡器中維護(hù)的信息作為分配依據(jù),并以此設(shè)計(jì)一些算法來實(shí)現(xiàn)針對(duì)特定場景的高效策略。
package com.netflix.loadbalancer; import com.netflix.client.IClientConfigAware; public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware { private ILoadBalancer lb; @Override public void setLoadBalancer(ILoadBalancer lb){ this.lb = lb; } @Override public ILoadBalancer getLoadBalancer(){ return lb; } }RandomRule
?該策略實(shí)現(xiàn)了從服務(wù)實(shí)例清單中隨機(jī)選擇一個(gè)服務(wù)實(shí)例的功能。下面先看一下源碼:
package com.netflix.loadbalancer; import java.util.List; import java.util.Random; import com.netflix.client.config.IClientConfig; public class RandomRule extends AbstractLoadBalancerRule { Random rand; public RandomRule() { rand = new Random(); } @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE") public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { if (Thread.interrupted()) { return null; } ListupList = lb.getReachableServers(); List allList = lb.getAllServers(); int serverCount = allList.size(); if (serverCount == 0) { /* * No servers. End regardless of pass, because subsequent passes * only get more restrictive. */ return null; } int index = rand.nextInt(serverCount); server = upList.get(index); if (server == null) { /* * The only time this should happen is if the server list were * somehow trimmed. This is a transient condition. Retry after * yielding. */ Thread.yield(); continue; } if (server.isAlive()) { return (server); } // Shouldn"t actually happen.. but must be transient or a bug. server = null; Thread.yield(); } return server; } @Override public Server choose(Object key) { return choose(getLoadBalancer(), key); } @Override public void initWithNiwsConfig(IClientConfig clientConfig) { // TODO Auto-generated method stub } }
?分析源碼可以看出,IRule接口中Server choose(Object key)函數(shù)的實(shí)現(xiàn)委托給了該類中的Server choose(ILoadBalancer lb, Object key)函數(shù),該方法增加了一個(gè)負(fù)載均衡器參數(shù)。從具體的實(shí)現(xiàn)可以看出,它會(huì)使用負(fù)載均衡器來獲得可用實(shí)例列表upList和所有的實(shí)例列表allList,并且使用rand.nextInt(serverCount)函數(shù)來獲取一個(gè)隨機(jī)數(shù),并將該隨機(jī)數(shù)作為upList的索引值來返回具體實(shí)例。同時(shí),具體的選擇邏輯在一個(gè)while (server == null)循環(huán)之內(nèi),而根據(jù)選擇邏輯的實(shí)現(xiàn),正常情況下每次都應(yīng)該選出一個(gè)服務(wù)實(shí)例,如果出現(xiàn)死循環(huán)獲取不到服務(wù)實(shí)例時(shí),則很有可能存在并發(fā)的Bug。
RoundRobinRule?該策略實(shí)現(xiàn)了按照線性輪詢的方式依次選擇每個(gè)服務(wù)實(shí)例的功能。下面看一下源碼:
package com.netflix.loadbalancer; import com.netflix.client.config.IClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class RoundRobinRule extends AbstractLoadBalancerRule { private AtomicInteger nextServerCyclicCounter; public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { log.warn("no load balancer"); return null; } Server server = null; int count = 0; while (server == null && count++ < 10) { ListreachableServers = lb.getReachableServers(); List allServers = lb.getAllServers(); int upCount = reachableServers.size(); int serverCount = allServers.size(); if ((upCount == 0) || (serverCount == 0)) { log.warn("No up servers available from load balancer: " + lb); return null; } int nextServerIndex = incrementAndGetModulo(serverCount); server = allServers.get(nextServerIndex); if (server == null) { /* Transient. */ Thread.yield(); continue; } if (server.isAlive() && (server.isReadyToServe())) { return (server); } // Next. server = null; } if (count >= 10) { log.warn("No available alive servers after 10 tries from load balancer: " + lb); } return server; } /** * Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}. * * @param modulo The modulo to bound the value of the counter. * @return The next value. */ private int incrementAndGetModulo(int modulo) { for (;;) { int current = nextServerCyclicCounter.get(); int next = (current + 1) % modulo; if (nextServerCyclicCounter.compareAndSet(current, next)) return next; } } }
?RoundRobinRule具體實(shí)現(xiàn)和RandomRule類似,但是循環(huán)條件和從可用列表獲取實(shí)例的邏輯不同。循環(huán)條件中增加了一個(gè)count計(jì)數(shù)變量,該變量會(huì)在每次循環(huán)之后累加,如果循環(huán)10次還沒獲取到Server,就會(huì)結(jié)束,并打印一個(gè)警告信息No available alive servers after 10 tries from load balancer:...。
?線性輪詢的實(shí)現(xiàn)是通過AtomicInteger nextServerCyclicCounter對(duì)象實(shí)現(xiàn),每次進(jìn)行實(shí)例選擇時(shí)通過調(diào)用int incrementAndGetModulo(int modulo)方法來實(shí)現(xiàn)。
RetryRule?該策略實(shí)現(xiàn)了一個(gè)具備重試機(jī)制的實(shí)例選擇功能。從源碼中可以看出,內(nèi)部定義了一個(gè)IRule對(duì)象,默認(rèn)是RoundRobinRule實(shí)例,choose方法中則實(shí)現(xiàn)了對(duì)內(nèi)部定義的策略進(jìn)行反復(fù)嘗試的策略,若期間能夠選擇到具體的服務(wù)實(shí)例就返回,若選擇不到并且超過設(shè)置的嘗試結(jié)束時(shí)間(maxRetryMillis參數(shù)定義的值 + choose方法開始執(zhí)行的時(shí)間戳)就返回null。
package com.netflix.loadbalancer; import com.netflix.client.config.IClientConfig; public class RetryRule extends AbstractLoadBalancerRule { IRule subRule = new RoundRobinRule(); long maxRetryMillis = 500; /* * Loop if necessary. Note that the time CAN be exceeded depending on the * subRule, because we"re not spawning additional threads and returning * early. */ public Server choose(ILoadBalancer lb, Object key) { long requestTime = System.currentTimeMillis(); long deadline = requestTime + maxRetryMillis; Server answer = null; answer = subRule.choose(key); if (((answer == null) || (!answer.isAlive())) && (System.currentTimeMillis() < deadline)) { InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis()); while (!Thread.interrupted()) { answer = subRule.choose(key); if (((answer == null) || (!answer.isAlive())) && (System.currentTimeMillis() < deadline)) { /* pause and retry hoping it"s transient */ Thread.yield(); } else { break; } } task.cancel(); } if ((answer == null) || (!answer.isAlive())) { return null; } else { return answer; } } }WeightedResponseTimeRule
?該策略是對(duì)RoundRobinRule的擴(kuò)展,增加了根據(jù)實(shí)例的運(yùn)行情況來計(jì)算權(quán)重,并根據(jù)權(quán)重來挑選實(shí)例,以達(dá)到更優(yōu)的分配效果。它的實(shí)現(xiàn)主要有三個(gè)核心內(nèi)容。
定時(shí)任務(wù)?WeightedResponseTimeRule策略在初始化的時(shí)候會(huì)通過serverWeightTimer.schedule(new DynamicServerWeightTask(), 0, serverWeightTaskTimerInterval)啟動(dòng)一個(gè)定時(shí)任務(wù),用來為每個(gè)服務(wù)實(shí)例計(jì)算權(quán)重,該任務(wù)默認(rèn)30s執(zhí)行一次。
權(quán)重計(jì)算?在源碼中我們可以輕松找到用于存儲(chǔ)權(quán)重的對(duì)象private volatile List
public void maintainWeights() { ILoadBalancer lb = getLoadBalancer(); if (lb == null) { return; } if (!serverWeightAssignmentInProgress.compareAndSet(false, true)) { return; } try { logger.info("Weight adjusting job started"); AbstractLoadBalancer nlb = (AbstractLoadBalancer) lb; LoadBalancerStats stats = nlb.getLoadBalancerStats(); if (stats == null) { // no statistics, nothing to do return; } double totalResponseTime = 0; // find maximal 95% response time for (Server server : nlb.getAllServers()) { // this will automatically load the stats if not in cache ServerStats ss = stats.getSingleServerStat(server); totalResponseTime += ss.getResponseTimeAvg(); } // weight for each server is (sum of responseTime of all servers - responseTime) // so that the longer the response time, the less the weight and the less likely to be chosen Double weightSoFar = 0.0; // create new list and hot swap the reference ListfinalWeights = new ArrayList (); for (Server server : nlb.getAllServers()) { ServerStats ss = stats.getSingleServerStat(server); double weight = totalResponseTime - ss.getResponseTimeAvg(); weightSoFar += weight; finalWeights.add(weightSoFar); } setWeights(finalWeights); } catch (Exception e) { logger.error("Error calculating server weights", e); } finally { serverWeightAssignmentInProgress.set(false); } }
?該方法的實(shí)現(xiàn)主要分為兩個(gè)步驟:
根據(jù)LoadBalancerStats中記錄的每個(gè)實(shí)例的統(tǒng)計(jì)信息,累加所有實(shí)例的平均響應(yīng)時(shí)間,得到總平均響應(yīng)時(shí)間totalResponseTime,該值會(huì)用于后續(xù)的計(jì)算。
為負(fù)載均衡器中維護(hù)的實(shí)例清單逐個(gè)計(jì)算權(quán)重(從第一個(gè)開始),計(jì)算規(guī)則為weightSoFar + totalResponseTime - 實(shí)例的平均響應(yīng)時(shí)間,其中weightSoFar初始化為0,并且每計(jì)算好一個(gè)權(quán)重需要累加到weightSoFar上供下一次計(jì)算使用。
?通過概算計(jì)算出來的權(quán)重值只是代表了各實(shí)例權(quán)重區(qū)間的上限。下面圖節(jié)選自Spring Cloud 微服務(wù)實(shí)戰(zhàn)。
?下面看一下Server choose(ILoadBalancer lb, Object key)如何選擇Server的
public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } Server server = null; while (server == null) { // get hold of the current reference in case it is changed from the other thread ListcurrentWeights = accumulatedWeights; if (Thread.interrupted()) { return null; } List allList = lb.getAllServers(); int serverCount = allList.size(); if (serverCount == 0) { return null; } int serverIndex = 0; // last one in the list is the sum of all weights double maxTotalWeight = currentWeights.size() == 0 ? 0 : currentWeights.get(currentWeights.size() - 1); // No server has been hit yet and total weight is not initialized // fallback to use round robin if (maxTotalWeight < 0.001d || serverCount != currentWeights.size()) { server = super.choose(getLoadBalancer(), key); if(server == null) { return server; } } else { // generate a random weight between 0 (inclusive) to maxTotalWeight (exclusive) double randomWeight = random.nextDouble() * maxTotalWeight; // pick the server index based on the randomIndex int n = 0; for (Double d : currentWeights) { if (d >= randomWeight) { serverIndex = n; break; } else { n++; } } server = allList.get(serverIndex); } if (server == null) { /* Transient. */ Thread.yield(); continue; } if (server.isAlive()) { return (server); } // Next. server = null; } return server; }
?下面我們看一下源碼的主要步驟有:
首先先獲取accumulatedWeights中最后一個(gè)權(quán)重,如果該權(quán)重小于0.001或者實(shí)例的數(shù)量不等于權(quán)重列表的數(shù)量,就采用父類的線性輪詢策略
如果滿足條件,就先產(chǎn)生一個(gè)[0,最大權(quán)重值)區(qū)間內(nèi)的隨機(jī)數(shù)
遍歷權(quán)重列表,比較權(quán)重值與隨機(jī)數(shù)的大小,如果權(quán)重值大于等于隨機(jī)數(shù),就拿當(dāng)前權(quán)重列表的索引值去服務(wù)實(shí)例列表獲取具體的實(shí)例。
?細(xì)心的可能會(huì)發(fā)現(xiàn)第一個(gè)服務(wù)實(shí)例的權(quán)重區(qū)間是雙閉,最后一個(gè)服務(wù)實(shí)例的權(quán)重區(qū)間是雙開,其他服務(wù)實(shí)例的區(qū)間都是左開右閉。這是因?yàn)殡S機(jī)數(shù)的最小值可以為0,所以第一個(gè)實(shí)例下限是閉區(qū)間,同時(shí)隨機(jī)數(shù)的最大值取不到最大權(quán)重值,所以最后一個(gè)實(shí)例的上限是開區(qū)間。
ClientConfigEnabledRoundRobinRule?該策略比較特殊,一般不直接使用它。因?yàn)樗旧聿]有實(shí)現(xiàn)特殊的處理邏輯,在他內(nèi)部定義了一個(gè)RoundRobinRule策略,choose函數(shù)的實(shí)現(xiàn)其實(shí)就是采用了RoundRobinRule的線性輪詢機(jī)制。
?在實(shí)際開發(fā)中,我們并不會(huì)直接使用該策略,而是基于它做高級(jí)策略擴(kuò)展。
BestAvailableRule?該策略繼承自ClientConfigEnabledRoundRobinRule,在實(shí)現(xiàn)中它注入了負(fù)載均衡器的統(tǒng)計(jì)對(duì)象LoadBalancerStats,同時(shí)在choose方法中利用LoadBalancerStats保存的實(shí)例統(tǒng)計(jì)信息來選擇滿足要求的服務(wù)實(shí)例。
?當(dāng)LoadBalancerStats為空時(shí),會(huì)使用RoundRobinRule線性輪詢策略,當(dāng)有LoadBalancerStats時(shí),會(huì)通過遍歷負(fù)載均衡器中維護(hù)的所有服務(wù)實(shí)例,會(huì)過濾掉故障的實(shí)例,并找出并發(fā)請(qǐng)求數(shù)最小的一個(gè)。
?該策略的特性是可以選出最空閑的服務(wù)實(shí)例。
PredicateBasedRule?這是一個(gè)抽象策略,它繼承了ClientConfigEnabledRoundRobinRule,從命名中可以猜出這是一個(gè)基于Predicate實(shí)現(xiàn)的策略,Predicate是Google Guava Collection工具對(duì)集合進(jìn)行過濾的條件接口。
public Server choose(Object key) { ILoadBalancer lb = getLoadBalancer(); Optionalserver = getPredicate().chooseRoundRobinAfterFiltering(lb.getAllServers(), key); if (server.isPresent()) { return server.get(); } else { return null; } }
?在該源碼中,它定義了一個(gè)抽象函數(shù)getPredicate來獲取AbstractServerPredicate對(duì)象的實(shí)現(xiàn),在choose方法中,通過AbstractServerPredicate的chooseRoundRobinAfterFiltering函數(shù)來選擇具體的服務(wù)實(shí)例。從該方法的命名我們可以看出大致的邏輯:首先通過子類中實(shí)現(xiàn)的Predicate邏輯來過濾一部分服務(wù)實(shí)例,然后再以線性輪詢的方式從過濾后的實(shí)例清單中選出一個(gè)。
?在上面choose函數(shù)中調(diào)用的chooseRoundRobinAfterFiltering方法先通過內(nèi)部定義的getEligibleServers函數(shù)來獲取備選的實(shí)例清單(實(shí)現(xiàn)了過濾),如果返回的清單為空,則用Optional.absent來表示不存在,反之則以線性輪詢的方式從備選清單中獲取一個(gè)實(shí)例。
?下面看一下getEligibleServers方法的源碼
public ListgetEligibleServers(List servers, Object loadBalancerKey) { if (loadBalancerKey == null) { return ImmutableList.copyOf(Iterables.filter(servers, this.getServerOnlyPredicate())); } else { List results = Lists.newArrayList(); for (Server server: servers) { if (this.apply(new PredicateKey(loadBalancerKey, server))) { results.add(server); } } return results; } }
?上述源碼的大致邏輯是遍歷服務(wù)清單,使用this.apply方法來判斷實(shí)例是否需要保留,如果是就添加到結(jié)果列表中。
?實(shí)際上,AbstractServerPredicate實(shí)現(xiàn)了com.google.common.base.Predicate接口,apply方法是接口中的定義,主要用來實(shí)現(xiàn)過濾條件的判斷邏輯,它輸入的參數(shù)則是過濾條件需要用到的一些信息(比如源碼中的new PredicateKey(loadBalancerKey, server)),傳入了關(guān)于實(shí)例的統(tǒng)計(jì)信息和負(fù)載均衡器的選擇算法傳遞過來的key。
?AbstractServerPredicate沒有apply的實(shí)現(xiàn),所以這里的chooseRoundRobinAfterFiltering方法只是定義了一個(gè)模板策略:先過濾清單,再輪詢選擇。
?對(duì)于如何過濾,需要在AbstractServerPredicate的子類中實(shí)現(xiàn)apply方法來確定具體的過濾策略。
AvailabilityFilteringRule&emsps;該類繼承自PredicateBasedRule,遵循了先過濾清單,再輪詢選擇的基本處理邏輯,其中過濾條件使用了AvailabilityPredicate,下面看一下AvailabilityPredicate的源碼:
package com.netflix.loadbalancer; import javax.annotation.Nullable; import com.netflix.client.config.IClientConfig; import com.netflix.config.ChainedDynamicProperty; import com.netflix.config.DynamicBooleanProperty; import com.netflix.config.DynamicIntProperty; import com.netflix.config.DynamicPropertyFactory; public class AvailabilityPredicate extends AbstractServerPredicate { @Override public boolean apply(@Nullable PredicateKey input) { LoadBalancerStats stats = getLBStats(); if (stats == null) { return true; } return !shouldSkipServer(stats.getSingleServerStat(input.getServer())); } private boolean shouldSkipServer(ServerStats stats) { if ((CIRCUIT_BREAKER_FILTERING.get() && stats.isCircuitBreakerTripped()) || stats.getActiveRequestsCount() >= activeConnectionsLimit.get()) { return true; } return false; } }
?從上面的源碼可以看出,主要過的過濾邏輯都是在boolean shouldSkipServer(ServerStats stats)方法中實(shí)現(xiàn),該方法主要判斷服務(wù)實(shí)例的兩項(xiàng)內(nèi)容:
是否故障,即斷路由器是否生效已斷開
實(shí)例的并發(fā)請(qǐng)求數(shù)大于閥值,默認(rèn)值2^32 - 1,該配置可以通過參數(shù)
?上面兩項(xiàng)只要滿足一項(xiàng),apply方法就返回false,代表該服務(wù)實(shí)例可能存在故障或負(fù)載過高,都不滿足就返回true。
?在AvailabilityFilteringRule進(jìn)行實(shí)例選擇時(shí)做了小小的優(yōu)化,它并沒有向父類一樣先遍歷所有的節(jié)點(diǎn)進(jìn)行過濾,然后在過濾后的集合中選擇實(shí)例。而是先以線性的方式選擇一個(gè)實(shí)例,接著使用過濾條件來判斷該實(shí)例是否滿足要求,若滿足就直接使用該實(shí)例,若不滿足要求就再選擇下一個(gè)實(shí)例,檢查是否滿足要求,這個(gè)過程循環(huán)10次如果還沒有找到合適的服務(wù)實(shí)例,就采用父類的實(shí)現(xiàn)方案。
?該策略通過線性輪詢的方式直接嘗試尋找可用且比較空閑的實(shí)例來用,優(yōu)化了每次都要遍歷所有實(shí)例的開銷。
ZoneAvoidanceRule?該類也是PredicateBasedRule的子類,它的實(shí)現(xiàn)是通過組合過濾條件CompositePredicate,以ZoneAvoidancePredicate為主過濾條件,以AvailabilityPredicate為次過濾條件。
?ZoneAvoidanceRule的實(shí)現(xiàn)并沒有像AvailabilityFilteringRule重寫choose函數(shù)來優(yōu)化,所以它遵循了先過濾清單再輪詢選擇的基本邏輯。
?下面看一下CompositePredicate的源碼
package com.netflix.loadbalancer; import java.util.Iterator; import java.util.List; import javax.annotation.Nullable; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Lists; public class CompositePredicate extends AbstractServerPredicate { private AbstractServerPredicate delegate; private Listfallbacks = Lists.newArrayList(); private int minimalFilteredServers = 1; private float minimalFilteredPercentage = 0; @Override public boolean apply(@Nullable PredicateKey input) { return delegate.apply(input); } @Override public List getEligibleServers(List servers, Object loadBalancerKey) { List result = super.getEligibleServers(servers, loadBalancerKey); Iterator i = fallbacks.iterator(); while (!(result.size() >= minimalFilteredServers && result.size() > (int) (servers.size() * minimalFilteredPercentage)) && i.hasNext()) { AbstractServerPredicate predicate = i.next(); result = predicate.getEligibleServers(servers, loadBalancerKey); } return result; } }
?從源碼中可以看出,CompositePredicate定義了一個(gè)主過濾條件delegate和一組過濾條件列表fallbacks,次過濾條件的過濾順序是按存儲(chǔ)順序執(zhí)行的。
?在獲取結(jié)果的getEligibleServers函數(shù)中的主要邏輯是:
使用主過濾條件對(duì)所有實(shí)例過濾并返回過濾后的實(shí)例清單
每次使用次過濾條件過濾前,都要判斷兩個(gè)條件,一個(gè)是過濾后的實(shí)例總數(shù) >= 最小過濾實(shí)例數(shù)(minimalFilteredServers,默認(rèn)值為1),另一個(gè)是過濾后的實(shí)例比例 > 最小過濾百分比(minimalFilteredPercentage,默認(rèn)為0),只要有一個(gè)不符合就不再進(jìn)行過濾,將當(dāng)前服務(wù)實(shí)例列表返回
依次使用次過濾條件列表中的過濾條件對(duì)主過濾條件的過濾結(jié)果進(jìn)行過濾。
后續(xù)后面會(huì)介紹Spring Cloud Ribbon配置方式,請(qǐng)持續(xù)關(guān)注!!!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/76744.html
摘要:中的名稱,一定要是服務(wù)中注冊(cè)的名稱。添加這個(gè)的注解,主要是因?yàn)槎x的時(shí)候報(bào)錯(cuò),也就是說明沒有被實(shí)例化。采用隨機(jī)分配的策略。添加訪問層添加電影微服務(wù)啟動(dòng)類電影微服務(wù),使用定制化在客戶端進(jìn)行負(fù)載均衡,使用不同服務(wù)不同配置策略。 SpringCloud(第 007 篇)電影微服務(wù),使用定制化 Ribbon 在客戶端進(jìn)行負(fù)載均衡,使用 RibbonClient 不同服務(wù)不同配置策略 - 一、大...
摘要:概要什么是實(shí)戰(zhàn)整合實(shí)現(xiàn)負(fù)載均衡是什么是一個(gè)客戶端負(fù)載均衡的組件什么是負(fù)載均衡負(fù)載均衡就是分發(fā)請(qǐng)求流量到不同的服務(wù)器目前的實(shí)現(xiàn)有軟件和硬件負(fù)載均衡分為兩種服務(wù)器端負(fù)載均衡如上圖所示服務(wù)器端負(fù)載均衡是對(duì)客戶透明的用戶請(qǐng)求到服務(wù)器真正的服務(wù)器是由 概要 什么是Spring Cloud Netflix Ribbon? 實(shí)戰(zhàn):整合Ribbon實(shí)現(xiàn)負(fù)載均衡 Spring Cloud Netfl...
摘要:代碼如下定義了用來存儲(chǔ)負(fù)載均衡器各服務(wù)實(shí)例屬性和統(tǒng)計(jì)信息的對(duì)象。下面看一下負(fù)載均衡器增加了哪些內(nèi)容。 客戶端負(fù)載均衡Spring Cloud Ribbon ?Spring Cloud Ribbon是一個(gè)基于HTTP和TCP的客戶端負(fù)載均衡工具,基于Netflix Ribbon實(shí)現(xiàn)。 目錄 客戶端負(fù)載均衡 源碼分析 負(fù)載均衡器(本文重點(diǎn)) 負(fù)載均衡策略 配置詳解 自動(dòng)化配置 客戶端負(fù)...
摘要:第篇電影微服務(wù),使用在客戶端進(jìn)行負(fù)載均衡一大致介紹是發(fā)布的云中間層服務(wù)開源項(xiàng)目,主要功能是提供客戶端負(fù)載均衡算法。而被注解后,能過用負(fù)載均衡,主要是維護(hù)了一個(gè)被注解的列表,并給列表中的添加攔截器,進(jìn)而交給負(fù)載均衡器去處理。 SpringCloud(第 006 篇)電影微服務(wù),使用 Ribbon 在客戶端進(jìn)行負(fù)載均衡 - 一、大致介紹 1、Ribbon 是 Netflix 發(fā)布的云中間層...
摘要:客戶端負(fù)載均衡需要客戶端自己維護(hù)自己要訪問的服務(wù)實(shí)例清單,這些服務(wù)清單來源于注冊(cè)中心在使用進(jìn)行服務(wù)治理時(shí)。使用從負(fù)載均衡器中挑選出的服務(wù)實(shí)例來執(zhí)行請(qǐng)求內(nèi)容。 客戶端負(fù)載均衡Spring Cloud Ribbon ?Spring Cloud Ribbon是一個(gè)基于HTTP和TCP的客戶端負(fù)載均衡工具,基于Netflix Ribbon實(shí)現(xiàn)。 目錄 客戶端負(fù)載均衡(本文重點(diǎn)) 源碼分析(本...
摘要:客戶端負(fù)載均衡器是一個(gè)客戶端負(fù)載均衡器,可以讓你對(duì)和客戶端的行為進(jìn)行大量控制,已經(jīng)使用了,因此,如果你使用,此部分也適用。 客戶端負(fù)載均衡器:Ribbon Ribbon是一個(gè)客戶端負(fù)載均衡器,可以讓你對(duì)HTTP和TCP客戶端的行為進(jìn)行大量控制,F(xiàn)eign已經(jīng)使用了Ribbon,因此,如果你使用@FeignClient,此部分也適用。 Ribbon中的一個(gè)核心概念是命名客戶端,每個(gè)負(fù)載均...
閱讀 2043·2023-04-26 02:15
閱讀 2309·2021-11-19 09:40
閱讀 1057·2021-10-27 14:13
閱讀 3326·2021-08-23 09:44
閱讀 3622·2019-12-27 12:24
閱讀 663·2019-08-30 15:53
閱讀 1180·2019-08-30 10:53
閱讀 2168·2019-08-26 12:14