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

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

package com.alibaba.dts.client.remoting;

import java.lang.reflect.InvocationHandler;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

import com.alibaba.dts.client.executor.grid.timer.HealthChecker;
import org.springframework.util.CollectionUtils;

import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
import com.alibaba.dts.client.remoting.processor.ClientRequestProcessor;
import com.alibaba.dts.client.remoting.proxy.ClientInvocationHandler;
import com.alibaba.dts.client.remoting.proxy.ClientSystemInvocationHandler;
import com.alibaba.dts.client.remoting.timer.DtsClientHeartBeatTimer;
import com.alibaba.dts.common.constants.Constants;
import com.alibaba.dts.common.context.InvocationContext;
import com.alibaba.dts.common.domain.remoting.RemoteMachine;
import com.alibaba.dts.common.domain.result.Result;
import com.alibaba.dts.common.exception.InitException;
import com.alibaba.dts.common.exception.RemotingConnectException;
import com.alibaba.dts.common.exception.RemotingSendRequestException;
import com.alibaba.dts.common.exception.RemotingTimeoutException;
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.protocol.RemotingCommand;
import com.alibaba.dts.common.service.ServerService;
import com.alibaba.dts.common.service.ServerSystemService;
import com.alibaba.dts.common.util.StringUtil;
import io.netty.channel.Channel;


public class ClientRemoting implements Constants {

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


    private NettyRemotingClient client = null;


    private ScheduledExecutorService dtsTimerService = 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 final InvocationHandler invocationHandler;
    private final InvocationHandler systemInvocationHandler;

    private final ServerService serverService;

    private final ServerSystemService serverSystemService;


    /** 心跳计数器映射表 */
//	private ConcurrentHashMap heartBeatCounterTable4Increase 	= new ConcurrentHashMap();
//	private ConcurrentHashMap heartBeatCounterTable4Compare 	= new ConcurrentHashMap();


    private volatile List serverListCache;
    private volatile List systemServerListCache;


    private final ClientContextImpl clientContext;

    public ClientRemoting(final ClientContextImpl clientContext) {
        this.clientContext = clientContext;

        this.invocationHandler = new ClientInvocationHandler(this.clientContext);
        this.serverService = proxyInterface(ServerService.class);

        this.systemInvocationHandler = new ClientSystemInvocationHandler(this.clientContext);
        this.serverSystemService = proxyInterface(ServerSystemService.class, systemInvocationHandler);
    }


    public void init() throws InitException {

        /** 初始化远程通信客户端 */
        initRemotingClient();

        /** 初始化连接 */
        initConnection();

        /** 初始化心跳定时器 */
        initHeartBeatTimer();
    }


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

        ClientRequestProcessor processor = new ClientRequestProcessor(this.clientContext);

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

            int index = 0;

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

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

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

                return thread;
            }

        }));

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


    private void initConnection() throws InitException {
        List serverList = getServerList();
//        List serverList = getSystemServerList();
        if (CollectionUtils.isEmpty(serverList)) {
            logger.warn("[ClientRemoting]: initConnection error, serverList is empty");
            return;
        }
        for (String server : serverList) {
            /** 连接服务器 */
            connectServer(server);
        }


    }

    public boolean connectServer(String server) throws InitException {

        long connectTime = System.currentTimeMillis();
        this.clientContext.getClientConfig().setConnectTime(connectTime);
        this.clientContext.getClientConfig().setSignature(this.clientContext.getSecurityCheck().getSignatureStr(connectTime));
        if (Constants.ENVIRONMENT_SCX.equals(clientContext.getClientConfig().getEnvironment())) {
            if (this.clientContext.getClientConfig().getAccessKey() == null) {
                throw new InitException("[ClientRemoting]: AK  is Null!");
            }
        }
        RemoteMachine remoteMachine = new RemoteMachine(server);
        remoteMachine.setH2Alive(HealthChecker.h2Alive.get());
        InvocationContext.setRemoteMachine(remoteMachine);
        Result connectResult = serverService.connect(StringUtil.isBlank(this.clientContext.getClientConfig().getAccessKey()) ? NULL : this.clientContext.getClientConfig().getAccessKey());
        if (null == connectResult) {
            logger.warn("[ClientRemoting]: connectServer failed, connectResult is null"
                    + ", machineGroup:" + this.clientContext.getClientConfig().getGroupId() + ", server:" + server);
            return false;
        }
        if (connectResult.getData().booleanValue()) {
        } else {
            logger.warn("[ClientRemoting]: connectServer failed"
                    + ", connectResult:" + connectResult.toString()
                    + ", machineGroup:" + this.clientContext.getClientConfig().getGroupId() + ", server:" + server + ",resp:" + connectResult.getResultCode().getInformation());

            throw new InitException("[ClientRemoting]: connectServer error," + connectResult.getResultCode().getInformation());
        }
        return true;
    }


    public List getServerList() {
        if (CollectionUtils.isEmpty(this.serverListCache)) {
            this.serverListCache = this.clientContext.getZookeeper().getServerList();
        }
        return this.serverListCache;
    }

    public List getSystemServerList() {
        if (CollectionUtils.isEmpty(this.systemServerListCache)) {
            this.systemServerListCache = this.clientContext.getZookeeper().getSystemServerList();
        }
        return this.systemServerListCache;
    }

    private void initHeartBeatTimer() throws InitException {
        try {

            dtsTimerService = Executors
                    .newScheduledThreadPool(1, new ThreadFactory() {

                        int index = 0;

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

                    });

            dtsTimerService.scheduleAtFixedRate(new DtsClientHeartBeatTimer(this.clientContext),
//                    this.clientContext.getClientConfig().getHeartBeatIntervalTime(),
                    0,
//                    this.clientContext.getClientConfig().getHeartBeatIntervalTime(),
                    10000,
                    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  T proxyInterface(Class interfaceClass) {
        return this.clientContext.getProxyService().proxyInterface(interfaceClass, invocationHandler);
    }

    public  T proxyInterface(Class interfaceClass, InvocationHandler invocationHandler) {
        return this.clientContext.getProxyService().proxyInterface(interfaceClass, invocationHandler);
    }


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

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


    public AtomicLong getCounter(ConcurrentHashMap heartBeatCounter, String key) {
        AtomicLong counter = heartBeatCounter.get(key);
        if (null == counter) {
            counter = new AtomicLong(0L);
            AtomicLong existCounter = heartBeatCounter.putIfAbsent(key, counter);
            if (existCounter != null) {
                counter = existCounter;
            }
        }
        return counter;
    }


    public void setServerListCache(List serverListCache) {
        this.serverListCache = serverListCache;
    }
    public void setSystemServerListCache(List serverListCache) {
        this.systemServerListCache = serverListCache;
    }

    public ServerSystemService getServerSystemService() {
        return serverSystemService;
    }

    public void stopService(){

        dtsTimerService.shutdownNow();

        client.shutdown();

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy