package org.apache.dubbo.rpc.cluster.loadbalance;
publicabstractclassAbstractLoadBalanceimplementsLoadBalance {
@Overridepublic <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {
if (CollectionUtils.isEmpty(invokers)) {
returnnull;
}
if (invokers.size() == 1) {
return invokers.get(0);
}
return doSelect(invokers, url, invocation);
}
protectedabstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);
/**
* Get the weight of the invoker's invocation which takes warmup time into account
* if the uptime is within the warmup time, the weight will be reduce proportionally
*
* @param invoker the invoker
* @param invocation the invocation of this invoker
* @return weight
*/intgetWeight(Invoker<?> invoker, Invocation invocation) {
int weight;
URLurl= invoker.getUrl();
// Multiple registry scenario, load balance among multiple registries.if (REGISTRY_SERVICE_REFERENCE_PATH.equals(url.getServiceInterface())) {
weight = url.getParameter(REGISTRY_KEY + "." + WEIGHT_KEY, DEFAULT_WEIGHT);
} else {
weight = url.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT);
if (weight > 0) {
longtimestamp= invoker.getUrl().getParameter(TIMESTAMP_KEY, 0L);
if (timestamp > 0L) {
longuptime= System.currentTimeMillis() - timestamp;
if (uptime < 0) {
return1;
}
intwarmup= invoker.getUrl().getParameter(WARMUP_KEY, DEFAULT_WARMUP);
if (uptime > 0 && uptime < warmup) {
weight = calculateWarmupWeight((int)uptime, warmup, weight);
}
}
}
}
return Math.max(weight, 0);
}
}
3. RandomLoadBalance加权随机算法
RandomLoadBalance实现类
package org.apache.dubbo.rpc.cluster.loadbalance;
publicclassRandomLoadBalanceextendsAbstractLoadBalance {
publicstaticfinalStringNAME="random";
/**
* 加权随机从invokers中选择一个
* @param invokers invokers集合
* @param url URL
* @param invocation Invocation
* @param <T>
* @return 选择的invoker
*/@Overrideprotected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
// Number of invokersintlength= invokers.size();
// Every invoker has the same weight?booleansameWeight=true;
// the weight of every invokersint[] weights = newint[length];
// the first invoker's weightintfirstWeight= getWeight(invokers.get(0), invocation);
weights[0] = firstWeight;
// The sum of weightsinttotalWeight= firstWeight;
for (inti=1; i < length; i++) {
intweight= getWeight(invokers.get(i), invocation);
// save for later use
weights[i] = weight;
// Sum
totalWeight += weight;
if (sameWeight && weight != firstWeight) {
sameWeight = false;
}
}
if (totalWeight > 0 && !sameWeight) {
// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.// 使用 ThreadLocalRandom.current().nextInt(length)从所有服务提供者里随机选择一个服务提供者进行调用。需要注意的是,这里没有使用Random而是使用了ThreadLocalRandom,这是出于性能上的考虑,因 为Random在高并发下会导致大量线程竞争同一个原子变量,导致大量线程原地自旋,从而浪费CPU资源intoffset= ThreadLocalRandom.current().nextInt(totalWeight);
// Return a invoker based on the random value.for (inti=0; i < length; i++) {
offset -= weights[i];
if (offset < 0) {
return invokers.get(i);
}
}
}
// If all invokers have the same weight value or totalWeight=0, return evenly.return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2010-02-02 解决在VS(winform)程序中无法在调试时修改代码的问题(也就是“编辑并继续”功能无效)
2009-02-02 使用反射机制将DataTable某行数据赋给一个类
2009-02-02 使用反射机制用一个类实例的值为DataTable添加一行
2009-02-02 使用反射机制将一个类实例的值赋给DataTable某一行
2009-02-02 使用2005+水晶报表报“CrystalDecisions.ReportSource.ReportSourceFactory”的类型初始值设定项引发异常。