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(); }}
阅读全文
0 0
- NettyRpc部分源码解析
- ArrayList 部分源码解析
- TreeSet部分源码解析
- phpcmsv9启动部分源码解析
- Mono概述及部分源码解析
- Mono概述及部分源码解析
- 关于fastjson序列化部分源码解析
- phpcmsv9源码解析 后台登录部分
- android短信源码部分解析(双卡)
- fastjson 序列化部分源码解析①
- fastjson 序列化部分源码解析②
- bootstrap源码解析-----------------样式重置部分
- Mono概述及部分源码解析
- Android地面站-MavLink解析部分源码
- Socket.io-client android 部分源码解析
- Flume-1.6.0部分源码解析
- react-redux部分关键源码解析
- Latke源码解析(一)Servlet部分
- [剑指offer]连续子数组的最大和
- python 核心编程(第三版)代码
- 441. Arranging Coins
- 机器语言、汇编语言、C语言(高级语言)的对比
- webpack CommonsChunkPlugin详细教程
- NettyRpc部分源码解析
- [总结]FFMPEG视音频编解码零基础学习方法
- Max Sum
- py初学者笔记
- mysql innodb_flush_log_at_trx_commit
- A
- 数码大师2010免费版
- SQL中EXISTS的用法
- Tensorflow:深度神经网络DNN预测波士顿房价(boston house price)【二】