dubbo RandomLoadBalance 源码
dubbo RandomLoadBalance 代码
文件路径:/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/loadbalance/RandomLoadBalance.java
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.loadbalance;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.ClusterInvoker;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_SERVICE_REFERENCE_PATH;
import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
/**
* This class select one provider from multiple providers randomly.
* You can define weights for each provider:
* If the weights are all the same then it will use random.nextInt(number of invokers).
* If the weights are different then it will use random.nextInt(w1 + w2 + ... + wn)
* Note that if the performance of the machine is better than others, you can set a larger weight.
* If the performance is not so good, you can set a smaller weight.
*/
public class RandomLoadBalance extends AbstractLoadBalance {
public static final String NAME = "random";
/**
* Select one invoker between a list using a random criteria
*
* @param invokers List of possible invokers
* @param url URL
* @param invocation Invocation
* @param <T>
* @return The selected invoker
*/
@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
// Number of invokers
int length = invokers.size();
if (!needWeightLoadBalance(invokers, invocation)) {
return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
// Every invoker has the same weight?
boolean sameWeight = true;
// the maxWeight of every invokers, the minWeight = 0 or the maxWeight of the last invoker
int[] weights = new int[length];
// The sum of weights
int totalWeight = 0;
for (int i = 0; i < length; i++) {
int weight = getWeight(invokers.get(i), invocation);
// Sum
totalWeight += weight;
// save for later use
weights[i] = totalWeight;
if (sameWeight && totalWeight != weight * (i + 1)) {
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.
int offset = ThreadLocalRandom.current().nextInt(totalWeight);
// Return a invoker based on the random value.
for (int i = 0; i < length; i++) {
if (offset < weights[i]) {
return invokers.get(i);
}
}
}
// If all invokers have the same weight value or totalWeight=0, return evenly.
return invokers.get(ThreadLocalRandom.current().nextInt(length));
}
private <T> boolean needWeightLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {
Invoker<T> invoker = invokers.get(0);
URL invokerUrl = invoker.getUrl();
if (invoker instanceof ClusterInvoker) {
invokerUrl = ((ClusterInvoker<?>) invoker).getRegistryUrl();
}
// Multiple registry scenario, load balance among multiple registries.
if (REGISTRY_SERVICE_REFERENCE_PATH.equals(invokerUrl.getServiceInterface())) {
String weight = invokerUrl.getParameter(WEIGHT_KEY);
return StringUtils.isNotEmpty(weight);
} else {
String weight = invokerUrl.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY);
if (StringUtils.isNotEmpty(weight)) {
return true;
} else {
String timeStamp = invoker.getUrl().getParameter(TIMESTAMP_KEY);
return StringUtils.isNotEmpty(timeStamp);
}
}
}
}
相关信息
相关文章
dubbo ConsistentHashLoadBalance 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦