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

com.alibaba.dts.client.remoting.NodeRemoting Maven / Gradle / Ivy

package com.alibaba.dts.client.remoting;

import java.lang.reflect.InvocationHandler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import com.alibaba.dts.client.executor.grid.ClientNodeRemotingServer;
import com.alibaba.dts.client.executor.grid.ClientNodeSystemRemotingServer;
import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
import com.alibaba.dts.client.executor.job.context.JobContext;
import com.alibaba.dts.client.executor.job.context.JobContextImpl;
import com.alibaba.dts.client.remoting.listener.ServerChannelEventListener;
import com.alibaba.dts.client.remoting.processor.NodeClientRequestProcessor;
import com.alibaba.dts.client.remoting.processor.NodeServerRequestProcessor;
import com.alibaba.dts.client.remoting.proxy.NodeClientInvocationHandler;
import com.alibaba.dts.client.remoting.proxy.NodeClientSystemInvocationHandler;
import com.alibaba.dts.client.remoting.proxy.NodeServerInvocationHandler;
import com.alibaba.dts.client.remoting.timer.NodeHeartBeatTimer;
import com.alibaba.dts.client.remoting.timer.NodeSnifferTimer;
import com.alibaba.dts.common.constants.Constants;
import com.alibaba.dts.common.context.InvocationContext;
import com.alibaba.dts.common.domain.ExecutableTask;
import com.alibaba.dts.common.domain.remoting.RemoteMachine;
import com.alibaba.dts.common.domain.result.Result;
import com.alibaba.dts.common.domain.result.ResultCode;
import com.alibaba.dts.common.domain.store.ExecutionCounter;
import com.alibaba.dts.common.domain.store.Job;
import com.alibaba.dts.common.domain.store.JobInstanceSnapshot;
import com.alibaba.dts.common.domain.store.TaskSnapshot;
import com.alibaba.dts.common.exception.*;
import com.alibaba.dts.common.logger.SchedulerXLoggerFactory;
import com.alibaba.dts.common.logger.innerlog.Logger;
import com.alibaba.dts.common.remoting.netty.NettyClientConfig;
import com.alibaba.dts.common.remoting.netty.NettyRemotingClient;
import com.alibaba.dts.common.remoting.netty.NettyRemotingServer;
import com.alibaba.dts.common.remoting.netty.NettyServerConfig;
import com.alibaba.dts.common.remoting.protocol.RemotingCommand;
import com.alibaba.dts.common.service.NodeClientService;
import com.alibaba.dts.common.service.NodeServerService;
import com.alibaba.dts.common.util.NamedThreadFactory;

import io.netty.channel.Channel;

/**
 * @author Ronan Zhan
 */
public class NodeRemoting implements Constants {

    private static final Logger logger = SchedulerXLoggerFactory.getLogger(NodeRemoting.class);

    public static volatile boolean isGetNodeIpsAvailable = true;

    //as client
    private NettyRemotingClient client;

    //as server
    private NettyRemotingServer server;
    private NettyRemotingServer systemServer;

    private NodeClientService nodeClientService;

    private NodeServerService nodeServerService;
    private NodeServerService nodeServerSystemService;


    private volatile List serverListCache;


    private volatile List nodeListCache;

    private ClientContextImpl clientContext;


    private InvocationHandler nodeServerInvocationHandler;
    private InvocationHandler nodeClientSystemInvocationHandler;

    private InvocationHandler nodeClientInvocationHandler;


    private ThreadPoolExecutor bizExecutors = null;

    private ThreadPoolExecutor systemExecutors = null;

    /**
     * 请求队列
     */
    private LinkedBlockingQueue requestQueue = new LinkedBlockingQueue();

    /**
     * 请求队列
     */
    private LinkedBlockingQueue systemRequestQueue = new LinkedBlockingQueue();

    /**
     * 连接的Node客户端
     */
    private ConcurrentHashMap clientNodes = new ConcurrentHashMap();


    private ConcurrentHashMap snifferedClientNodes = new ConcurrentHashMap();

    /**
     * 客户端嗅探线程池
     */
    private ScheduledExecutorService nodeSnifferExecutorService = Executors
            .newScheduledThreadPool(1, new ThreadFactory() {

                int index = 0;

                @Override
                public Thread newThread(Runnable runnable) {
                    index++;
                    return new Thread(runnable, "Schedulerx-Server-Sniffer-Thread-" + index);
                }

            });

    /**
     * 定时调度服务
     */
    private ScheduledExecutorService timeExecutorService = Executors
            .newScheduledThreadPool(1, new ThreadFactory() {

                int index = 0;

                @Override
                public Thread newThread(Runnable runnable) {
                    index++;
                    return new Thread(runnable, HEART_BEAT_THREAD_NAME + index);
                }

            });

    private ExecutorService taskReSendExecutorService = Executors.newSingleThreadExecutor(
            new NamedThreadFactory("Task-ReSend-Thread-"));
    private ExecutorService taskDealFailExecutorService = Executors.newSingleThreadExecutor(
            new NamedThreadFactory("Task-DealFail-Thread-"));

    private ExecutorService nodeAliveCheckExecutorService = Executors.newFixedThreadPool(10,
            new NamedThreadFactory("SchedulerX-Node-Alive-Check-Thread-"));

    public static volatile AtomicBoolean isNodeHeartBeatRunning = new AtomicBoolean(false);

    public NodeRemoting(ClientContextImpl clientContext) {
        this.clientContext = clientContext;
        nodeClientInvocationHandler = new NodeClientInvocationHandler(clientContext);
        nodeServerInvocationHandler = new NodeServerInvocationHandler(clientContext);
        nodeClientSystemInvocationHandler = new NodeClientSystemInvocationHandler(clientContext);
        nodeServerService = proxyServerInterface();
        nodeServerSystemService = proxyServerSystemInterface();
        nodeClientService = proxyClientInterface();
    }


    public void init() throws InitException {

        initNodeServer();
        initNodeSystemServer();
        initNodeClient();
        initNodeHeartbeatTimer();
    }

    private void initNodeSystemServer() throws InitException {
        NettyServerConfig config = new NettyServerConfig();
        /** 设置监听端口 */
        config.setListenPort(clientContext.getNodeConfig().getSystemListenPort());
        logger.info("local system listen port is {}", clientContext.getNodeConfig().getSystemListenPort());

        NodeServerRequestProcessor systemProcessor = new NodeServerRequestProcessor(systemRequestQueue, clientContext);
        systemProcessor.init();

        ServerChannelEventListener listener = new ServerChannelEventListener(clientContext);

//        systemServer = new NettyRemotingServer(config, listener);
        systemServer = new ClientNodeSystemRemotingServer(config, listener, this.clientContext);

        systemExecutors = new ThreadPoolExecutor(clientContext.getNodeConfig().getRemotingThreads(),
                clientContext.getNodeConfig().getRemotingThreads(),
                0L, TimeUnit.MILLISECONDS,
                systemRequestQueue,
                new ThreadFactory() {

                    int index = 0;

                    @Override
                    public Thread newThread(Runnable runnable) {
                        index++;
                        return new Thread(runnable, SYSTEM_NODE_REMOTING_THREAD_NAME + index);
                    }

                });

        systemServer.registerProcessor(REQUEST_CODE, systemProcessor, systemExecutors);
        try {
            systemServer.start();
        } catch (Throwable e) {
            throw new InitException("[ServerRemoting]: init error", e);
        }
    }

    private void initNodeServer() throws InitException {

        NettyServerConfig config = new NettyServerConfig();
        /** 设置监听端口 */
        config.setListenPort(clientContext.getNodeConfig().getListenPort());
        logger.info("local listen port is {}", clientContext.getNodeConfig().getListenPort());

        NodeServerRequestProcessor bizProcessor = new NodeServerRequestProcessor(requestQueue, clientContext);

        bizProcessor.init();

        ServerChannelEventListener listener = new ServerChannelEventListener(clientContext);

//        server = new NettyRemotingServer(config, listener);
        server = new ClientNodeRemotingServer(config, listener, clientContext);

        bizExecutors = new ThreadPoolExecutor(clientContext.getNodeConfig().getRemotingThreads(),
                clientContext.getNodeConfig().getRemotingThreads(),
                0L, TimeUnit.MILLISECONDS,
                requestQueue,
                new ThreadFactory() {

                    int index = 0;

                    @Override
                    public Thread newThread(Runnable runnable) {
                        index++;
                        return new Thread(runnable, NODE_REMOTING_THREAD_NAME + index);
                    }

                });

        server.registerProcessor(REQUEST_CODE, bizProcessor, bizExecutors);
        try {
            server.start();
        } catch (Throwable e) {
            throw new InitException("[ServerRemoting]: init error", e);
        }
    }

    private void initNodeClient() throws InitException {
        NettyClientConfig config = new NettyClientConfig();

        NodeClientRequestProcessor processor = new NodeClientRequestProcessor(clientContext);

        client = new NettyRemotingClient(config);
        client.registerProcessor(REQUEST_CODE, processor,
                Executors.newFixedThreadPool(clientContext.getNodeConfig().getRemotingThreads(), new ThreadFactory() {

                    int index = 0;

                    @Override
                    public Thread newThread(Runnable runnable) {
                        index++;

                        Thread thread = new Thread(runnable, NODE_CLIENT_REMOTING_THREAD_NAME + index);

                        //设置通信线程更高优先级
                        thread.setPriority(10);

                        return thread;
                    }

                }));

        try {
            client.start();
        } catch (Throwable e) {
            throw new InitException("[ClientRemoting]: initRemotingClient error", e);
        }

    }

    private void initNodeHeartbeatTimer() throws InitException {
        try {
            nodeSnifferExecutorService.scheduleAtFixedRate(
                    new NodeSnifferTimer(clientContext),
                    0,
                    clientContext.getNodeConfig().getHeartbeatInterval() * 3 /* 30秒 */, TimeUnit.MILLISECONDS);

            timeExecutorService.scheduleAtFixedRate(
                    new NodeHeartBeatTimer(this.clientContext),
                    0,
                    clientContext.getNodeConfig().getHeartbeatInterval(), TimeUnit.MILLISECONDS);
        } catch (Throwable e) {
            throw new InitException("[ClientRemoting]: initHeartBeatTimer error"
                    + ", heartBeatIntervalTime:" + this.clientContext.getClientConfig().getHeartBeatIntervalTime(), e);
        }
        logger.warn("[ClientRemoting]: initHeartBeatTimer success"
                + ", heartBeatIntervalTime:" + this.clientContext.getClientConfig().getHeartBeatIntervalTime());

    }

    public void connectNodes(List remoteMachines) throws InitException, InterruptedException {
        if (remoteMachines == null || remoteMachines.isEmpty()) {
            return;
        }
        final CountDownLatch latch = new CountDownLatch(remoteMachines.size());
        for (final RemoteMachine remoteMachine : remoteMachines) {
            nodeAliveCheckExecutorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        connectNode(remoteMachine);
                    } catch (Throwable throwable) {
                        logger.warn("failed to connect to node " + remoteMachine, throwable);
                    } finally {
                        latch.countDown();
                    }
                }
            });

        }
        latch.await();
    }

    private void connectNode(RemoteMachine remoteMachine) {
        try {
            String key = remoteMachine.getRemoteAddress() + ":" + remoteMachine.getNodeSystemListenPort();
            final String systemRemoteAddress = remoteMachine.getSystemRemoteAddress();
            if (!clientNodes.containsKey(key)) {
                clientNodes.put(key, 0);
                snifferedClientNodes.put(key, new AtomicInteger(0));
            }

            long connectTime = System.currentTimeMillis();
            clientContext.getNodeConfig().setConnectTime(connectTime);

            InvocationContext.setRemoteMachine(remoteMachine);
            remoteMachine.setTimeout(10 * 1000);
            Result connectResult = nodeServerSystemService.connect();
            if (null == connectResult) {
//                logger.error("failed to connect to node , connectResult is null"
//                    + ", machineGroup:" + clientContext.getNodeConfig().getGroupId() + ", remoteMachine:"
//                    + systemRemoteAddress);
                dealConnectFailed(key, remoteMachine.getRemoteAddress());
                return;
            }
            if (connectResult.getData().booleanValue()) {
                clientNodes.put(key, 0);
                snifferedClientNodes.put(key, new AtomicInteger(0));
            } else {
//                logger.error("failed to connect to node"
//                    + ", connectResult:" + connectResult.toString()
//                    + ", clientGroup:" + clientContext.getNodeConfig().getGroupId() + ", remoteMachine:" + remoteMachine
//                    .getSystemRemoteAddress() + ",resp:" + connectResult.getResultCode().getInformation());
                dealConnectFailed(key, remoteMachine.getRemoteAddress());
                throw new InitException(
                        "[ClientRemoting]: connectServer error," + connectResult.getResultCode().getInformation());
            }
        } catch (Throwable throwable) {
            logger.warn("failed to connect to node " + remoteMachine.getRemoteAddress(), throwable);
        }
    }

    private void dealConnectFailed(String key, String remoteAddress) {
        int missingCount = clientNodes.get(key) + 1;
        if (missingCount >= 4) {
            clientNodes.remove(key);
            snifferedClientNodes.remove(key);
            logger.info("remove " + key + " from clientNodes");
            logger.warn("failed to connect to node , connectResult is null"
                    + ", clientGroup: " + clientContext.getNodeConfig().getGroupId() + ", remoteMachine: "
                    + key + ", failed count: " + missingCount);
            if (clientContext.getNodeConfig().isEnableRedispatch()) {
                reSendTasks(remoteAddress);
            } else {
                setTasksFail(remoteAddress);
            }
        } else {
            clientNodes.put(key, missingCount);
            snifferedClientNodes.put(key, new AtomicInteger(missingCount));
        }
    }

    private void setTasksFail(final String remoteAddress) {
        taskDealFailExecutorService.submit(new Runnable() {
            private List jobs = new ArrayList();
            private List jobInstanceSnapshots = new ArrayList();

            @Override
            public void run() {
                try {

                    for (ConcurrentHashMap>
                            executionCounterMapByReceiveNode : clientContext
                            .getExecutionCounterTable().values()) {
                        for (ConcurrentHashMap executionCounterMapByTaskName :
                                executionCounterMapByReceiveNode
                                        .values()) {
                            for (ExecutionCounter executionCounter : executionCounterMapByTaskName.values()) {
                                if (remoteAddress.equals(executionCounter.getReceiveNode())) {
                                    executionCounter.getFailCounter().set(
                                            executionCounter.getFailCounter().get() + executionCounter.getQueuedCounter()
                                                    .get());
                                    executionCounter.getQueuedCounter().set(0);
                                }
                            }
                        }
                    }

                    long count = clientContext.getStore().getTaskSnapshotDao().deleteByReceiveNodeAddressAndStatus(
                            remoteAddress, Constants.TASK_STATUS_QUEUE);
                    while (count > 0) {
                        count = clientContext.getStore().getTaskSnapshotDao().deleteByReceiveNodeAddressAndStatus(
                                remoteAddress, Constants.TASK_STATUS_QUEUE);
                    }
                } catch (Throwable throwable) {
                    logger.error("failed to reSend tasks, receiveNodeAddress=" + remoteAddress, throwable);
                }

            }
        });
    }

    private void reSendTasks(final String remoteAddress) {
        taskReSendExecutorService.submit(new Runnable() {
            private List jobs = new ArrayList();
            private List jobInstanceSnapshots = new ArrayList();

            @Override
            public void run() {
                try {

                    for (ConcurrentHashMap>
                            executionCounterMapByReceiveNode : clientContext
                            .getExecutionCounterTable().values()) {
                        for (ConcurrentHashMap executionCounterMapByTaskName :
                                executionCounterMapByReceiveNode
                                        .values()) {
                            for (ExecutionCounter executionCounter : executionCounterMapByTaskName.values()) {
                                if (remoteAddress.equals(executionCounter.getReceiveNode())) {
                                    executionCounter.getTotalCounter().set(
                                            executionCounter.getSuccessCounter().get() + executionCounter.getFailCounter()
                                                    .get());
                                    executionCounter.getQueuedCounter().set(0);
                                }
                            }
                        }
                    }

                    List taskSnapshots = listReSendTasks(0);

                    while (taskSnapshots != null && !taskSnapshots.isEmpty()) {

                        List executableTasks = new ArrayList();
                        for (TaskSnapshot taskSnapshot : taskSnapshots) {
                            taskSnapshot.setCompensation(true);
                            long jobInstanceId = taskSnapshot.getJobInstanceId();

                            JobInstanceSnapshot jobInstanceSnapshot = getJobInstanceExisted(jobInstanceId);
                            if (jobInstanceSnapshot == null) {

                                Result result = getJobInstance(jobInstanceId);
                                if (result == null || result.getResultCode() != ResultCode.SUCCESS) {
                                    return;
                                }
                                jobInstanceSnapshot = result.getData();
                                jobInstanceSnapshots.add(jobInstanceSnapshot);
                            }

                            Job job = getJobExisted(jobInstanceSnapshot.getJobId());
                            if (job == null) {

                                Result result = getJob(jobInstanceSnapshot.getJobId());
                                if (result == null || result.getResultCode() != ResultCode.SUCCESS) {
                                    return;
                                }
                                job = result.getData();
                                jobs.add(job);
                            }

                            ExecutableTask executableTask = getExecutableTask(executableTasks, jobInstanceId);
                            if (executableTask == null) {
                                executableTask = new ExecutableTask();
                                executableTask.setJobInstanceSnapshot(jobInstanceSnapshot);
                                executableTask.setJob(job);
                                executableTasks.add(executableTask);
                            }
                            executableTask.getTaskSnapshotList().add(taskSnapshot);
                        }

                        for (ExecutableTask executableTask : executableTasks) {
                            JobContext jobContext = new JobContextImpl();
                            jobContext.setJob(executableTask.getJob());
                            jobContext.setJobInstanceSnapshot(executableTask.getJobInstanceSnapshot());
                            Result result = clientContext.getGridTaskSender().dispatchCompensateTaskList(
                                    executableTask.getTaskSnapshotList(), jobContext);
                            if (result != null && result.getData() == true) {
                                //                                updateTasksStatus2Retrying(executableTask);
                            }
                        }

                        long start = taskSnapshots.get(taskSnapshots.size() - 1).getId();
                        taskSnapshots = listReSendTasks(start);

                    }
                } catch (Throwable throwable) {
                    logger.error("failed to reSend tasks, receiveNodeAddress=" + remoteAddress, throwable);
                }

            }

            private List listReSendTasks(long startId) {
                List taskSnapshots = null;
                try {
                    taskSnapshots = clientContext.getStore().getTaskSnapshotDao().listByIdAndReceiveNodeAndStatus(
                            startId, remoteAddress, Constants.TASK_STATUS_QUEUE);
                } catch (AccessException e) {
                    logger.error("", e);
                }

                return taskSnapshots;
            }

            private Job getJobExisted(long jobId) {
                for (Job job : jobs) {
                    if (job.getId() == jobId) {
                        return job;
                    }
                }
                return null;
            }

            private JobInstanceSnapshot getJobInstanceExisted(long jobInstanceId) {
                for (JobInstanceSnapshot jobInstanceSnapshot : jobInstanceSnapshots) {
                    if (jobInstanceSnapshot.getId() == jobInstanceId) {
                        return jobInstanceSnapshot;
                    }
                }
                return null;
            }

            private Result getJobInstance(long jobInstanceId) {
                List serverList = clientContext.getClientRemoting().getServerList();

                Result result = null;
                for (String server : serverList) {
                    InvocationContext.setRemoteMachine(new RemoteMachine(server));
                    result = clientContext.getServerService().getJobInstanceById(jobInstanceId);
                    if (result == null) {
                        logger.error(
                                "clientContext getServerService getJobInstanceById error from server {} with job instance"
                                        + " id {}",
                                server, jobInstanceId);
                        continue;
                    } else {
                        break;
                    }
                }
                return result;
            }

            private Result getJob(long jobId) {
                List serverList = clientContext.getClientRemoting().getServerList();

                Result result = null;
                for (String server : serverList) {
                    InvocationContext.setRemoteMachine(new RemoteMachine(server));
                    result = clientContext.getServerService().getJobById(jobId);
                    if (result == null) {
                        logger.error("clientContext getServerService getJobById error from server {} with job id {}",
                                server, jobId);
                        continue;
                    } else {
                        break;
                    }
                }
                return result;
            }

            private ExecutableTask getExecutableTask(List executableTasks, long jobInstanceId) {
                for (ExecutableTask executableTask : executableTasks) {
                    if (executableTask.getJobInstanceSnapshot().getId() == jobInstanceId) {
                        return executableTask;
                    }
                }
                return null;
            }
        });
    }


    public NodeClientService proxyClientInterface() {
        return clientContext.getProxyService().proxyInterface(NodeClientService.class, nodeServerInvocationHandler);
    }

    public NodeServerService proxyServerInterface() {
        return clientContext.getProxyService().proxyInterface(NodeServerService.class, nodeClientInvocationHandler);
    }

    private NodeServerService proxyServerSystemInterface() {
        return clientContext.getProxyService().proxyInterface(NodeServerService.class,
                nodeClientSystemInvocationHandler);
    }


    public RemotingCommand invokeSync(final Channel channel, final RemotingCommand request, final long timeoutMillis)
            throws InterruptedException, RemotingSendRequestException, RemotingTimeoutException {
        return server.invokeSync(channel, request, timeoutMillis);
    }


    public RemotingCommand invokeSync(String addr, final RemotingCommand request, long timeoutMillis)
            throws InterruptedException, RemotingConnectException, RemotingSendRequestException, RemotingTimeoutException {
        return client.invokeSync(addr, request, timeoutMillis);
    }

    public void deleteConnection(String remoteAddress) {

    }


    public Channel getAndCreateChannel(final String addr) throws InterruptedException {
        return client.getAndCreateChannel(addr);
    }

    public List getNodes(String groupId, long jobId, int jobType) {

        List remoteMachines = new ArrayList();
        try {
            List serverList = clientContext.getClientRemoting().getServerList();
            if (serverList == null || serverList.isEmpty()) {
                return remoteMachines;
            }
            Collections.shuffle(serverList);
            String localAddressWithListenPort = clientContext.getNodeConfig().getLocalAddress();
            List remoteNodes = new ArrayList();

            for (String serverAddress : serverList) {
                try {
                    InvocationContext.setRemoteMachine(new RemoteMachine(serverAddress));

                    if (isGetNodeIpsAvailable) {
                        remoteNodes = clientContext.getClientRemoting().getServerSystemService().getNodeIps(groupId, jobId, jobType);
                        if (remoteNodes == null || remoteNodes.size() == 0) {
                            continue;
                        }

                        for (final String remoteNode : remoteNodes) {
                            RemoteMachine remoteMachine = new RemoteMachine();
                            String[] ipPorts = remoteNode.split(":");
                            String remoteIp = ipPorts[0];
                            int nodeListenPort = Integer.valueOf(ipPorts[1]);
                            int systemNodeListenPort = Integer.valueOf(ipPorts[2]);
                            String remoteAddress = remoteIp + ":" + nodeListenPort;

                            if (!(remoteNodes.size() > 1 && localAddressWithListenPort.equals(remoteAddress) && clientContext.getNodeConfig().isDispatchOnly())) {
                                String systemRemoteAddress = remoteIp + ":" + systemNodeListenPort;
                                remoteMachine.setRemoteAddress(remoteAddress);
                                remoteMachine.setSystemRemoteAddress(systemRemoteAddress);
                                remoteMachines.add(remoteMachine);
                            }
                        }
                        return remoteMachines;
                    } else {
                        remoteMachines = clientContext.getServerService().getRemoteMachines(groupId, jobId);
                        Iterator remoteMachineIterator = remoteMachines.iterator();
                        while (remoteMachineIterator.hasNext()) {
                            RemoteMachine remoteMachine = remoteMachineIterator.next();
                            String remoteIp = remoteMachine.getRemoteAddress().substring(0,
                                    remoteMachine.getRemoteAddress().indexOf(":"));
                            String remoteAddress = remoteIp + ":" + remoteMachine.getNodeListenPort();
                            String systemRemoteAddress = remoteIp + ":" + remoteMachine.getNodeSystemListenPort();
                            if (remoteMachines.size() > 1 && localAddressWithListenPort.equals(remoteAddress)
                                    && clientContext.getNodeConfig().isDispatchOnly()) {
                                remoteMachineIterator.remove();
                            } else {
                                remoteMachine.setRemoteAddress(remoteAddress);
                                remoteMachine.setSystemRemoteAddress(systemRemoteAddress);
                            }
                        }
                        if (remoteMachines.size() > 0) {
                            return remoteMachines;
                        }
                    }
                } catch (Throwable e) {
                    logger.error("getNodes error,serverAddress:" + serverAddress, e);
                }
            }
        } catch (Throwable e) {
            logger.error("getServerList error", e);
        }
        return remoteMachines;
    }

    public ConcurrentHashMap getClientNodes() {
        return clientNodes;
    }

    public void sniffer(RemoteMachine remoteMachine) {
        InvocationContext.setRemoteMachine(remoteMachine);
        remoteMachine.setTimeout(10 * 1000);
        Result connectResult = nodeServerSystemService.connect();

        StringBuilder sb = new StringBuilder();
        sb.append(remoteMachine.getRemoteAddress()).append(":").append(remoteMachine.getNodeSystemListenPort());
        String key = sb.toString();

        if (null == connectResult || connectResult.getData() != true) {
            AtomicInteger failedCount = snifferedClientNodes.get(key);
            if (failedCount != null) {
                failedCount.getAndIncrement();
                if (failedCount.get() >= 4 && failedCount.get() % 4 == 0) {
                    logger.warn("failed to sniffer node , connectResult is null"
                            + ", machineGroup:" + clientContext.getNodeConfig().getGroupId() + ", remoteMachine: " + key + ", failedCount: " + failedCount.get());
                }
            } else {
                failedCount = new AtomicInteger(1);
                AtomicInteger failedCountExisted = snifferedClientNodes.putIfAbsent(key, failedCount);
                if (failedCountExisted != null) {
                    failedCount = failedCountExisted;
                    failedCountExisted.getAndIncrement();
                }
            }


            if (failedCount.get() >= 16) {
                snifferedClientNodes.remove(key);
                logger.info("remove " + key + " from snifferedClientNodes");
            }
            return;
        } else {
            clientNodes.put(key, 0);
            snifferedClientNodes.put(key, new AtomicInteger(0));
        }
    }
    public void stopService() {
        nodeSnifferExecutorService.shutdownNow();
        timeExecutorService.shutdownNow();
    }

    public NodeServerService getNodeServerService() {
        return nodeServerService;
    }

    public NodeServerService getNodeServerSystemService() {
        return nodeServerSystemService;
    }

    public NodeClientService getNodeClientService() {
        return nodeClientService;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy