CalvinKirs
4 years ago
32 changed files with 347 additions and 651 deletions
@ -1,17 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.client; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
|
||||||
|
|
||||||
/** |
|
||||||
* ConsumerInvoker |
|
||||||
*/ |
|
||||||
public class ConsumerInvoker implements Invoker { |
|
||||||
@Override |
|
||||||
public RpcResponse invoke(RpcRequest req) throws Throwable { |
|
||||||
|
|
||||||
System.out.println(req.getRequestId()+"kris"); |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
@ -1,59 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.directory; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.filter.SelectorFilter; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collections; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||||
|
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
/** |
|
||||||
* Directory |
|
||||||
*/ |
|
||||||
public class Directory { |
|
||||||
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Directory.class); |
|
||||||
|
|
||||||
|
|
||||||
private SelectorFilter selectorFilter = SelectorFilter.getInstance(); |
|
||||||
|
|
||||||
public static Directory getInstance() { |
|
||||||
return Directory.DirectoryInner.INSTANCE; |
|
||||||
} |
|
||||||
|
|
||||||
private static class DirectoryInner { |
|
||||||
|
|
||||||
private static final Directory INSTANCE = new Directory(); |
|
||||||
} |
|
||||||
|
|
||||||
private Directory() { |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
private ConcurrentHashMap<String, List<String>> directoryMap = new ConcurrentHashMap<>(); |
|
||||||
|
|
||||||
public List<String> getDirectory(String serviceName) { |
|
||||||
return directoryMap.get(serviceName); |
|
||||||
} |
|
||||||
|
|
||||||
public boolean addServer(String serviceName, String servicePath) { |
|
||||||
synchronized (this) { |
|
||||||
if (directoryMap.containsKey(serviceName)) { |
|
||||||
directoryMap.get(serviceName).add(servicePath); |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
directoryMap.putIfAbsent(serviceName, new ArrayList<>(Collections.singletonList(servicePath))); |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
public boolean removeServer(String serviceName, String servicePath) { |
|
||||||
|
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
|
||||||
|
|
||||||
|
|
||||||
import com.amazonaws.Response; |
|
||||||
|
|
||||||
|
|
||||||
public interface Filter { |
|
||||||
|
|
||||||
|
|
||||||
RpcResponse filter(Invoker invoker, RpcRequest req) throws Throwable; |
|
||||||
} |
|
@ -1,38 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
|
||||||
|
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* FilterChain |
|
||||||
*/ |
|
||||||
public class FilterChain { |
|
||||||
|
|
||||||
|
|
||||||
private List<Filter> filters; |
|
||||||
|
|
||||||
private Invoker invoker; |
|
||||||
|
|
||||||
|
|
||||||
public FilterChain(List<Filter> filters, Invoker invoker) { |
|
||||||
this.filters = filters; |
|
||||||
this.invoker = invoker; |
|
||||||
} |
|
||||||
|
|
||||||
public FilterChain(Invoker invoker) { |
|
||||||
this(LoaderFilters.create().getFilters(), invoker); |
|
||||||
} |
|
||||||
|
|
||||||
public Invoker buildFilterChain() { |
|
||||||
// 最后一个
|
|
||||||
Invoker last = invoker; |
|
||||||
|
|
||||||
for (int i = filters.size() - 1; i >= 0; i--) { |
|
||||||
last = new FilterWrapper(filters.get(i), last); |
|
||||||
} |
|
||||||
// 第一个
|
|
||||||
return last; |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -1,33 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
|
||||||
import org.apache.dolphinscheduler.remote.utils.Host; |
|
||||||
|
|
||||||
/** |
|
||||||
* @author jiangli |
|
||||||
* @date 2021-01-11 11:48 |
|
||||||
*/ |
|
||||||
public class FilterWrapper implements Invoker { |
|
||||||
|
|
||||||
|
|
||||||
private Filter next; |
|
||||||
|
|
||||||
private Invoker invoker; |
|
||||||
|
|
||||||
|
|
||||||
public FilterWrapper(Filter next, Invoker invoker) { |
|
||||||
this.next = next; |
|
||||||
this.invoker = invoker; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public RpcResponse invoke(RpcRequest args) throws Throwable { |
|
||||||
if (next != null) { |
|
||||||
return next.filter(invoker, args); |
|
||||||
} else { |
|
||||||
return invoker.invoke(args); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,26 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
/** |
|
||||||
* LoaderFilters |
|
||||||
*/ |
|
||||||
public class LoaderFilters { |
|
||||||
|
|
||||||
|
|
||||||
private List<Filter> filterList = new ArrayList<>(); |
|
||||||
|
|
||||||
private LoaderFilters() { |
|
||||||
} |
|
||||||
|
|
||||||
public static LoaderFilters create() { |
|
||||||
|
|
||||||
return new LoaderFilters(); |
|
||||||
} |
|
||||||
|
|
||||||
public List<Filter> getFilters() { |
|
||||||
filterList.add(SelectorFilter.getInstance()); |
|
||||||
return filterList; |
|
||||||
} |
|
||||||
} |
|
@ -1,60 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.filter; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.Invoker; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcRequest; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.common.RpcResponse; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.directory.Directory; |
|
||||||
import org.apache.dolphinscheduler.remote.rpc.selector.RandomSelector; |
|
||||||
import org.apache.dolphinscheduler.remote.utils.Host; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* SelectorFilter |
|
||||||
*/ |
|
||||||
public class SelectorFilter implements Filter { |
|
||||||
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SelectorFilter.class); |
|
||||||
|
|
||||||
|
|
||||||
private SelectorFilter selectorFilter = SelectorFilter.getInstance(); |
|
||||||
|
|
||||||
public static SelectorFilter getInstance() { |
|
||||||
return SelectorFilterInner.INSTANCE; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
private static class SelectorFilterInner { |
|
||||||
|
|
||||||
private static final SelectorFilter INSTANCE = new SelectorFilter(); |
|
||||||
} |
|
||||||
|
|
||||||
private SelectorFilter() { |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public RpcResponse filter(Invoker invoker, RpcRequest req) throws Throwable { |
|
||||||
Directory.getInstance().addServer("default","127.0.0.1:8080"); |
|
||||||
Directory.getInstance().addServer("default","127.0.0.2:8080"); |
|
||||||
Directory.getInstance().addServer("default","127.0.0.3:8080"); |
|
||||||
List<String> hosts = Directory.getInstance().getDirectory("default"); |
|
||||||
List<Host> candidateHosts = new ArrayList<>(hosts.size()); |
|
||||||
hosts.forEach(node -> { |
|
||||||
Host nodeHost = Host.of(node); |
|
||||||
nodeHost.setWorkGroup("default"); |
|
||||||
candidateHosts.add(nodeHost); |
|
||||||
}); |
|
||||||
RandomSelector randomSelector = new RandomSelector(); |
|
||||||
System.out.println(randomSelector.doSelect(candidateHosts)); |
|
||||||
RpcResponse rsp = new RpcResponse(); |
|
||||||
rsp.setMsg("ms"); |
|
||||||
return rsp; |
|
||||||
} |
|
||||||
} |
|
@ -1,87 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.dolphinscheduler.remote.rpc.filter.selector; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.utils.Constants; |
|
||||||
import org.apache.dolphinscheduler.remote.utils.Host; |
|
||||||
|
|
||||||
/** |
|
||||||
* host weight |
|
||||||
*/ |
|
||||||
public class HostWeight { |
|
||||||
|
|
||||||
private final int CPU_FACTOR = 10; |
|
||||||
|
|
||||||
private final int MEMORY_FACTOR = 20; |
|
||||||
|
|
||||||
private final int LOAD_AVERAGE_FACTOR = 70; |
|
||||||
|
|
||||||
private final Host host; |
|
||||||
|
|
||||||
private final double weight; |
|
||||||
|
|
||||||
private double currentWeight; |
|
||||||
|
|
||||||
public HostWeight(Host host, double cpu, double memory, double loadAverage) { |
|
||||||
this.weight = getWeight(cpu, memory, loadAverage, host); |
|
||||||
this.host = host; |
|
||||||
this.currentWeight = weight; |
|
||||||
} |
|
||||||
|
|
||||||
public double getCurrentWeight() { |
|
||||||
return currentWeight; |
|
||||||
} |
|
||||||
|
|
||||||
public double getWeight() { |
|
||||||
return weight; |
|
||||||
} |
|
||||||
|
|
||||||
public void setCurrentWeight(double currentWeight) { |
|
||||||
this.currentWeight = currentWeight; |
|
||||||
} |
|
||||||
|
|
||||||
public Host getHost() { |
|
||||||
return host; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String toString() { |
|
||||||
return "HostWeight{" |
|
||||||
+ "host=" + host |
|
||||||
+ ", weight=" + weight |
|
||||||
+ ", currentWeight=" + currentWeight |
|
||||||
+ '}'; |
|
||||||
} |
|
||||||
|
|
||||||
private double getWeight(double cpu, double memory, double loadAverage, Host host) { |
|
||||||
double calculateWeight = cpu * CPU_FACTOR + memory * MEMORY_FACTOR + loadAverage * LOAD_AVERAGE_FACTOR; |
|
||||||
return getWarmUpWeight(host, calculateWeight); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* If the warm-up is not over, add the weight |
|
||||||
*/ |
|
||||||
private double getWarmUpWeight(Host host, double weight) { |
|
||||||
long startTime = host.getStartTime(); |
|
||||||
long uptime = System.currentTimeMillis() - startTime; |
|
||||||
if (uptime > 0 && uptime < Constants.WARM_UP_TIME) { |
|
||||||
return weight * Constants.WARM_UP_TIME / uptime; |
|
||||||
} |
|
||||||
return weight; |
|
||||||
} |
|
||||||
} |
|
@ -1,56 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.dolphinscheduler.remote.rpc.filter.selector; |
|
||||||
|
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.selector.AbstractSelector; |
|
||||||
|
|
||||||
import java.util.Collection; |
|
||||||
|
|
||||||
/** |
|
||||||
* lower weight round robin |
|
||||||
*/ |
|
||||||
public class LowerWeightRoundRobin extends AbstractSelector<HostWeight> { |
|
||||||
|
|
||||||
/** |
|
||||||
* select |
|
||||||
* |
|
||||||
* @param sources sources |
|
||||||
* @return HostWeight |
|
||||||
*/ |
|
||||||
@Override |
|
||||||
public HostWeight doSelect(Collection<HostWeight> sources) { |
|
||||||
double totalWeight = 0; |
|
||||||
double lowWeight = 0; |
|
||||||
HostWeight lowerNode = null; |
|
||||||
for (HostWeight hostWeight : sources) { |
|
||||||
totalWeight += hostWeight.getWeight(); |
|
||||||
hostWeight.setCurrentWeight(hostWeight.getCurrentWeight() + hostWeight.getWeight()); |
|
||||||
if (lowerNode == null || lowWeight > hostWeight.getCurrentWeight()) { |
|
||||||
lowerNode = hostWeight; |
|
||||||
lowWeight = hostWeight.getCurrentWeight(); |
|
||||||
} |
|
||||||
} |
|
||||||
lowerNode.setCurrentWeight(lowerNode.getCurrentWeight() + totalWeight); |
|
||||||
return lowerNode; |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,141 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.dolphinscheduler.remote.rpc.filter.selector; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.rpc.selector.AbstractSelector; |
|
||||||
import org.apache.dolphinscheduler.remote.utils.Host; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||||
import java.util.concurrent.ConcurrentMap; |
|
||||||
import java.util.concurrent.atomic.AtomicBoolean; |
|
||||||
import java.util.concurrent.atomic.AtomicLong; |
|
||||||
|
|
||||||
|
|
||||||
/** |
|
||||||
* Smooth Weight Round Robin |
|
||||||
*/ |
|
||||||
public class RoundRobinSelector extends AbstractSelector<Host> { |
|
||||||
|
|
||||||
private ConcurrentMap<String, ConcurrentMap<String, WeightedRoundRobin>> workGroupWeightMap = new ConcurrentHashMap<>(); |
|
||||||
|
|
||||||
private static final int RECYCLE_PERIOD = 100000; |
|
||||||
|
|
||||||
private AtomicBoolean updateLock = new AtomicBoolean(); |
|
||||||
|
|
||||||
protected static class WeightedRoundRobin { |
|
||||||
private int weight; |
|
||||||
private AtomicLong current = new AtomicLong(0); |
|
||||||
private long lastUpdate; |
|
||||||
|
|
||||||
int getWeight() { |
|
||||||
return weight; |
|
||||||
} |
|
||||||
|
|
||||||
void setWeight(int weight) { |
|
||||||
this.weight = weight; |
|
||||||
current.set(0); |
|
||||||
} |
|
||||||
|
|
||||||
long increaseCurrent() { |
|
||||||
return current.addAndGet(weight); |
|
||||||
} |
|
||||||
|
|
||||||
void sel(int total) { |
|
||||||
current.addAndGet(-1L * total); |
|
||||||
} |
|
||||||
|
|
||||||
long getLastUpdate() { |
|
||||||
return lastUpdate; |
|
||||||
} |
|
||||||
|
|
||||||
void setLastUpdate(long lastUpdate) { |
|
||||||
this.lastUpdate = lastUpdate; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
public Host doSelect(Collection<Host> source) { |
|
||||||
|
|
||||||
List<Host> hosts = new ArrayList<>(source); |
|
||||||
String key = hosts.get(0).getWorkGroup(); |
|
||||||
ConcurrentMap<String, WeightedRoundRobin> map = workGroupWeightMap.get(key); |
|
||||||
if (map == null) { |
|
||||||
workGroupWeightMap.putIfAbsent(key, new ConcurrentHashMap<>()); |
|
||||||
map = workGroupWeightMap.get(key); |
|
||||||
} |
|
||||||
|
|
||||||
int totalWeight = 0; |
|
||||||
long maxCurrent = Long.MIN_VALUE; |
|
||||||
long now = System.currentTimeMillis(); |
|
||||||
Host selectedHost = null; |
|
||||||
WeightedRoundRobin selectWeightRoundRobin = null; |
|
||||||
|
|
||||||
for (Host host : hosts) { |
|
||||||
String workGroupHost = host.getWorkGroup() + host.getAddress(); |
|
||||||
WeightedRoundRobin weightedRoundRobin = map.get(workGroupHost); |
|
||||||
int weight = host.getWeight(); |
|
||||||
if (weight < 0) { |
|
||||||
weight = 0; |
|
||||||
} |
|
||||||
|
|
||||||
if (weightedRoundRobin == null) { |
|
||||||
weightedRoundRobin = new WeightedRoundRobin(); |
|
||||||
// set weight
|
|
||||||
weightedRoundRobin.setWeight(weight); |
|
||||||
map.putIfAbsent(workGroupHost, weightedRoundRobin); |
|
||||||
weightedRoundRobin = map.get(workGroupHost); |
|
||||||
} |
|
||||||
if (weight != weightedRoundRobin.getWeight()) { |
|
||||||
weightedRoundRobin.setWeight(weight); |
|
||||||
} |
|
||||||
|
|
||||||
long cur = weightedRoundRobin.increaseCurrent(); |
|
||||||
weightedRoundRobin.setLastUpdate(now); |
|
||||||
if (cur > maxCurrent) { |
|
||||||
maxCurrent = cur; |
|
||||||
selectedHost = host; |
|
||||||
selectWeightRoundRobin = weightedRoundRobin; |
|
||||||
} |
|
||||||
|
|
||||||
totalWeight += weight; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
if (!updateLock.get() && hosts.size() != map.size() && updateLock.compareAndSet(false, true)) { |
|
||||||
try { |
|
||||||
ConcurrentMap<String, WeightedRoundRobin> newMap = new ConcurrentHashMap<>(map); |
|
||||||
newMap.entrySet().removeIf(item -> now - item.getValue().getLastUpdate() > RECYCLE_PERIOD); |
|
||||||
workGroupWeightMap.put(key, newMap); |
|
||||||
} finally { |
|
||||||
updateLock.set(false); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (selectedHost != null) { |
|
||||||
selectWeightRoundRobin.sel(totalWeight); |
|
||||||
return selectedHost; |
|
||||||
} |
|
||||||
|
|
||||||
return hosts.get(0); |
|
||||||
} |
|
||||||
} |
|
@ -1,29 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.common.utils.CollectionUtils; |
|
||||||
|
|
||||||
import java.util.Collection; |
|
||||||
|
|
||||||
/** |
|
||||||
* AbstractSelector |
|
||||||
*/ |
|
||||||
public abstract class AbstractSelector<T> implements Selector<T>{ |
|
||||||
@Override |
|
||||||
public T select(Collection<T> source) { |
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(source)) { |
|
||||||
throw new IllegalArgumentException("Empty source."); |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* if only one , return directly |
|
||||||
*/ |
|
||||||
if (source.size() == 1) { |
|
||||||
return (T)source.toArray()[0]; |
|
||||||
} |
|
||||||
return doSelect(source); |
|
||||||
} |
|
||||||
|
|
||||||
protected abstract T doSelect(Collection<T> source); |
|
||||||
|
|
||||||
} |
|
@ -1,44 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
|
||||||
|
|
||||||
import org.apache.dolphinscheduler.remote.utils.Host; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.Collection; |
|
||||||
import java.util.List; |
|
||||||
import java.util.concurrent.ThreadLocalRandom; |
|
||||||
|
|
||||||
/** |
|
||||||
* RandomSelector |
|
||||||
*/ |
|
||||||
public class RandomSelector extends AbstractSelector<Host> { |
|
||||||
|
|
||||||
@Override |
|
||||||
public Host doSelect(final Collection<Host> source) { |
|
||||||
|
|
||||||
List<Host> hosts = new ArrayList<>(source); |
|
||||||
int size = hosts.size(); |
|
||||||
int[] weights = new int[size]; |
|
||||||
int totalWeight = 0; |
|
||||||
int index = 0; |
|
||||||
|
|
||||||
for (Host host : hosts) { |
|
||||||
totalWeight += host.getWeight(); |
|
||||||
weights[index] = host.getWeight(); |
|
||||||
index++; |
|
||||||
} |
|
||||||
|
|
||||||
if (totalWeight > 0) { |
|
||||||
int offset = ThreadLocalRandom.current().nextInt(totalWeight); |
|
||||||
|
|
||||||
for (int i = 0; i < size; i++) { |
|
||||||
offset -= weights[i]; |
|
||||||
if (offset < 0) { |
|
||||||
return hosts.get(i); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return hosts.get(ThreadLocalRandom.current().nextInt(size)); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
@ -1,16 +0,0 @@ |
|||||||
package org.apache.dolphinscheduler.remote.rpc.selector; |
|
||||||
|
|
||||||
import java.util.Collection; |
|
||||||
|
|
||||||
/** |
|
||||||
* Selector |
|
||||||
*/ |
|
||||||
public interface Selector<T> { |
|
||||||
|
|
||||||
/** |
|
||||||
* select |
|
||||||
* @param source source |
|
||||||
* @return T |
|
||||||
*/ |
|
||||||
T select(Collection<T> source); |
|
||||||
} |
|
Loading…
Reference in new issue