com.alibaba.schedulerx.worker.route.WorkerLoadRouter Maven / Gradle / Ivy
package com.alibaba.schedulerx.worker.route;
import com.alibaba.schedulerx.common.util.StringUtils;
import com.alibaba.schedulerx.worker.metrics.WorkerLoad;
import com.alibaba.schedulerx.worker.metrics.WorkerLoadRegister;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
* 基于Worker load路由
* @author yaohui
*/
public class WorkerLoadRouter extends Router implements WorkerLoadRegister {
private int index = 0;
private static final Random r = new Random();
private Map workerLoadMap = Maps.newHashMap();
@Override
public void init(String strategyContent) {}
@Override
public String route(long appGroupId, long jobId, List workerList, Map> targetWorkerAddsMap,
long loopCount, String masterWorkerIdAddr) {
int size = workerList.size();
if (size == 0) {
return null;
}
List availableWorkers = Lists.newArrayList();
synchronized (this) {
while (CollectionUtils.isEmpty(availableWorkers)) {
// 优先选择没有被选中过的机器
size = workerList.size();
for (int i = 0; i < size; i++, index++) {
if (index < 0) {
index = 0;
}
WorkerLoad workerLoad = this.workerLoadMap.get(workerList.get(index%size));
if (workerLoad == null) {
this.getWorkLoad(workerList.get(index%size));
return workerList.get(index%size);
} else {
if (workerLoad.isAvailable()) {
availableWorkers.add(workerList.get(index%size));
}
}
}
try {
if (CollectionUtils.isEmpty(availableWorkers)) {
LOGGER.info("wait available worker. worker size:{}", workerList.size());
this.wait(15 * 1000);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
String selected = null;
if (availableWorkers.size() > 1) {
int a = r.nextInt(availableWorkers.size());
int b = r.nextInt(availableWorkers.size() - 1);
if (b == a) {
// 防止随机出的节点相同
b += 1;
}
String workerA = availableWorkers.get(a);
String workerB = availableWorkers.get(b);
// 为了保障主节点的负载安全,优选选取非主节点
if (StringUtils.equals(workerA, masterWorkerIdAddr)) {
selected = workerB;
} else if (StringUtils.equals(workerB, masterWorkerIdAddr)) {
selected = workerA;
} else {
if (workerLoadMap.get(workerA).getWeight() > workerLoadMap.get(workerB).getWeight()) {
selected = workerA;
} else {
selected = workerB;
}
}
} else {
selected = availableWorkers.get(0);
}
// // 扣减可用数量
// workerLoadMap.get(selected).descAvailable();
return selected;
}
@Override
public void set(String workerAddr, WorkerLoad workerLoad) {
workerLoadMap.put(workerAddr, workerLoad);
}
@Override
public void setAvailableSize(String workerAddr, Integer availableSize) {
WorkerLoad workerLoad = getWorkLoad(workerAddr);
workerLoad.setAvailableSize(availableSize);
}
@Override
public void setRemainCpu(String workerAddr, Integer remainCpu) {
WorkerLoad workerLoad = getWorkLoad(workerAddr);
workerLoad.setRemainCpu(remainCpu);
}
@Override
public void setRemainMemory(String workerAddr, Long remainMemory) {
WorkerLoad workerLoad = getWorkLoad(workerAddr);
workerLoad.setRemainMemory(remainMemory);
}
@Override
public void setCost(String workerAddr, Long cost) {
WorkerLoad workerLoad = getWorkLoad(workerAddr);
workerLoad.setCost(cost);
}
private WorkerLoad getWorkLoad(String workerAddr){
WorkerLoad workerLoad = workerLoadMap.get(workerAddr);
if (workerLoad == null) {
synchronized (workerLoadMap) {
workerLoad = workerLoadMap.get(workerAddr);
if (workerLoad == null) {
workerLoad = new WorkerLoad(workerAddr);
workerLoadMap.put(workerAddr, workerLoad);
}
}
}
return workerLoad;
}
@Override
public void clear() {
this.workerLoadMap.clear();
}
public static void main(String[] args) {
Integer a = 10;
a--;
System.out.println(a);
}
}