NettyRpc部分源码解析

来源:互联网 发布:学python和java哪个好 编辑:程序博客网 时间:2024/05/21 22:33
package com.nettyrpc.client;import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.concurrent.*;import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantLock;/** * Created by luxiaoxun on 2016-03-16. */public class ConnectManage {    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectManage.class);    private volatile static ConnectManage connectManage;    EventLoopGroup eventLoopGroup = new NioEventLoopGroup(4);    private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(16, 16, 600L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(65536));    private CopyOnWriteArrayList<RpcClientHandler> connectedHandlers = new CopyOnWriteArrayList<RpcClientHandler>();    private Map<InetSocketAddress, RpcClientHandler> connectedServerNodes = new ConcurrentHashMap<InetSocketAddress, RpcClientHandler>();    //private Map<InetSocketAddress, Channel> connectedServerNodes = new ConcurrentHashMap<>();    private ReentrantLock lock = new ReentrantLock();    private Condition connected = lock.newCondition();    protected long connectTimeoutMillis = 6000;    private AtomicInteger roundRobin = new AtomicInteger(0);    private volatile boolean isRuning = true;    private ConnectManage() {    }    public static ConnectManage getInstance() {        if (connectManage == null) {            synchronized (ConnectManage.class) {                if (connectManage == null) {                    connectManage = new ConnectManage();                }            }        }        return connectManage;    }    public void updateConnectedServer(List<String> allServerAddress) {        if (allServerAddress != null) {            if (allServerAddress.size() > 0) {  // Get available server node                //update local serverNodes cache                HashSet<InetSocketAddress> newAllServerNodeSet = new HashSet<InetSocketAddress>();                for (int i = 0; i < allServerAddress.size(); ++i) {                    String[] array = allServerAddress.get(i).split(":");                    if (array.length == 2) { // Should check IP and port                        String host = array[0];                        int port = Integer.parseInt(array[1]);                        final InetSocketAddress remotePeer = new InetSocketAddress(host, port);                        newAllServerNodeSet.add(remotePeer);                    }                }                // Add new server node                for (final InetSocketAddress serverNodeAddress : newAllServerNodeSet) {                    if (!connectedServerNodes.keySet().contains(serverNodeAddress)) {                        connectServerNode(serverNodeAddress);                    }                }                // Close and remove invalid server nodes                for (int i = 0; i < connectedHandlers.size(); ++i) {                    RpcClientHandler connectedServerHandler = connectedHandlers.get(i);                    SocketAddress remotePeer = connectedServerHandler.getRemotePeer();                    if (!newAllServerNodeSet.contains(remotePeer)) {                        LOGGER.info("Remove invalid server node " + remotePeer);                        RpcClientHandler handler = connectedServerNodes.get(remotePeer);                        handler.close();                        connectedServerNodes.remove(remotePeer);                        connectedHandlers.remove(connectedServerHandler);                    }                }            } else { // No available server node ( All server nodes are down )                LOGGER.error("No available server node. All server nodes are down !!!");                for (final RpcClientHandler connectedServerHandler : connectedHandlers) {                    SocketAddress remotePeer = connectedServerHandler.getRemotePeer();                    RpcClientHandler handler = connectedServerNodes.get(remotePeer);                    handler.close();                    connectedServerNodes.remove(connectedServerHandler);                }                connectedHandlers.clear();            }        }    }    public void  reconnect(final RpcClientHandler handler, final SocketAddress remotePeer){        if(handler!=null){            connectedHandlers.remove(handler);            connectedServerNodes.remove(handler.getRemotePeer());        }        connectServerNode((InetSocketAddress)remotePeer);    }    private void connectServerNode(final InetSocketAddress remotePeer) {        threadPoolExecutor.submit(new Runnable() {            @Override            public void run() {                Bootstrap b = new Bootstrap();                b.group(eventLoopGroup)                        .channel(NioSocketChannel.class)                        .handler(new RpcClientInitializer());                ChannelFuture channelFuture = b.connect(remotePeer);                channelFuture.addListener(new ChannelFutureListener() {                    @Override                    public void operationComplete(final ChannelFuture channelFuture) throws Exception {                        if (channelFuture.isSuccess()) {                            LOGGER.debug("Successfully connect to remote server. remote peer = " + remotePeer);                            RpcClientHandler handler = channelFuture.channel().pipeline().get(RpcClientHandler.class);                            addHandler(handler);                        }                    }                });            }        });    }    private void addHandler(RpcClientHandler handler) {        connectedHandlers.add(handler);        InetSocketAddress remoteAddress = (InetSocketAddress) handler.getChannel().remoteAddress();        connectedServerNodes.put(remoteAddress, handler);        signalAvailableHandler();    }    private void signalAvailableHandler() {        lock.lock();        try {            connected.signalAll();        } finally {            lock.unlock();        }    }    private boolean waitingForHandler() throws InterruptedException {        lock.lock();        try {            return connected.await(this.connectTimeoutMillis, TimeUnit.MILLISECONDS);        } finally {            lock.unlock();        }    }    public RpcClientHandler chooseHandler() {        CopyOnWriteArrayList<RpcClientHandler> handlers = (CopyOnWriteArrayList<RpcClientHandler>) this.connectedHandlers.clone();        int size = handlers.size();        while (isRuning && size <= 0) {            try {                boolean available = waitingForHandler();                if (available) {                    handlers = (CopyOnWriteArrayList<RpcClientHandler>) this.connectedHandlers.clone();                    size = handlers.size();                }            } catch (InterruptedException e) {                LOGGER.error("Waiting for available node is interrupted! ", e);                throw new RuntimeException("Can't connect any servers!", e);            }        }        int index = (roundRobin.getAndAdd(1) + size) % size;        return handlers.get(index);    }    public void stop(){        isRuning = false;        for (int i = 0; i < connectedHandlers.size(); ++i) {            RpcClientHandler connectedServerHandler = connectedHandlers.get(i);            connectedServerHandler.close();        }        signalAvailableHandler();        threadPoolExecutor.shutdown();        eventLoopGroup.shutdownGracefully();    }}

原创粉丝点击