All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance Maven / Gradle / Ivy

There is a newer version: 3.3.0-beta.2
Show newest version
/*
 * 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.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcStatus;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * ShortestResponseLoadBalance
 * 

* Filter the number of invokers with the shortest response time of success calls and count the weights and quantities of these invokers. * If there is only one invoker, use the invoker directly; * if there are multiple invokers and the weights are not the same, then random according to the total weight; * if there are multiple invokers and the same weight, then randomly called. */ public class ShortestResponseLoadBalance extends AbstractLoadBalance { public static final String NAME = "shortestresponse"; @Override protected Invoker doSelect(List> invokers, URL url, Invocation invocation) { // Number of invokers int length = invokers.size(); // Estimated shortest response time of all invokers long shortestResponse = Long.MAX_VALUE; // The number of invokers having the same estimated shortest response time int shortestCount = 0; // The index of invokers having the same estimated shortest response time int[] shortestIndexes = new int[length]; // the weight of every invokers int[] weights = new int[length]; // The sum of the warmup weights of all the shortest response invokers int totalWeight = 0; // The weight of the first shortest response invokers int firstWeight = 0; // Every shortest response invoker has the same weight value? boolean sameWeight = true; // Filter out all the shortest response invokers for (int i = 0; i < length; i++) { Invoker invoker = invokers.get(i); RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()); // Calculate the estimated response time from the product of active connections and succeeded average elapsed time. long succeededAverageElapsed = rpcStatus.getSucceededAverageElapsed(); int active = rpcStatus.getActive() + 1; long estimateResponse = succeededAverageElapsed * active; int afterWarmup = getWeight(invoker, invocation); weights[i] = afterWarmup; // Same as LeastActiveLoadBalance if (estimateResponse < shortestResponse) { shortestResponse = estimateResponse; shortestCount = 1; shortestIndexes[0] = i; totalWeight = afterWarmup; firstWeight = afterWarmup; sameWeight = true; } else if (estimateResponse == shortestResponse) { shortestIndexes[shortestCount++] = i; totalWeight += afterWarmup; if (sameWeight && i > 0 && afterWarmup != firstWeight) { sameWeight = false; } } } if (shortestCount == 1) { return invokers.get(shortestIndexes[0]); } if (!sameWeight && totalWeight > 0) { int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight); for (int i = 0; i < shortestCount; i++) { int shortestIndex = shortestIndexes[i]; offsetWeight -= weights[shortestIndex]; if (offsetWeight < 0) { return invokers.get(shortestIndex); } } } return invokers.get(shortestIndexes[ThreadLocalRandom.current().nextInt(shortestCount)]); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy