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

com.alibaba.schedulerx.worker.route.WorkerLoadRouter Maven / Gradle / Ivy

There is a newer version: 1.12.2
Show newest version
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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy