package com.my.lionrpc.client; import java.net.InetSocketAddress; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.my.lionrpc.protocol.RequestMessage; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelOption; import io.netty.channel.epoll.Epoll; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.epoll.EpollSocketChannel; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; /** * * @author littlechen * */ public class LionConnectionManager { private static final Logger LOGGER = LoggerFactory.getLogger(LionConnectionManager.class); private AtomicInteger threadCount = new AtomicInteger(1); private LinkedBlockingDeque<Channel> connectionPoll = new LinkedBlockingDeque<Channel>(); private ConcurrentHashMap<String, Channel> connectionMap = new ConcurrentHashMap<String, Channel>(); private LionConnectionManager() {} private static final LionConnectionManager instance = new LionConnectionManager(); public static LionConnectionManager getInstance(){ return instance; } public synchronized void connectServer(List<String> allServerAddress){ int cpu = Runtime.getRuntime().availableProcessors(); if(allServerAddress != null && allServerAddress.size() > 0){ for(final String remotePeer:allServerAddress){ Iterator<String> keyIter = connectionMap.keySet().iterator(); boolean flag = false; while(keyIter.hasNext()){ String key = keyIter.next(); if(key.contains(remotePeer)){ flag=true; break; } } if(flag)continue; for(int i = 1;i <= cpu ;i++){ connectServerNode(remotePeer,i); } } }else{ Iterator<String> iterator = connectionMap.keySet().iterator(); while(iterator.hasNext()){ String key = iterator.next(); try{ Channel channel = connectionMap.get(key); channel.close(); }catch(Exception e){} } connectionMap.clear(); } } public void getConnectionAndSendRequest(RequestMessage request){ Channel channel = null; try { channel = connectionPoll.take(); while(channel != null){ if(channel.isOpen()){ channel.writeAndFlush(request); return; }else{ LOGGER.error("连接已经断开:"+channel.remoteAddress()); channel = connectionPoll.take(); } } } catch (Exception e) { LOGGER.error("getConnectionAndSendRequest happen exception.", e); }finally{ if(channel != null && channel.isOpen()){ connectionPoll.offer(channel); } } } public void connectServerNode(final String remotePeer,final int index){ int cpu = Runtime.getRuntime().availableProcessors(); int loopCount = cpu; try{ Bootstrap boot = new Bootstrap(); if(Epoll.isAvailable()){ boot.channel(EpollSocketChannel.class); boot.group(new EpollEventLoopGroup(loopCount,new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("EpollEventLoopGroupThread-"+threadCount.getAndIncrement()); return t; } })); }else{ boot.channel(NioSocketChannel.class); boot.group(new NioEventLoopGroup(loopCount,new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("NioEventLoopGroup-"+threadCount.getAndIncrement()); return t; } })); } boot.option(ChannelOption.TCP_NODELAY, true); boot.handler(new LionClientChannelInitializer()); String[] ar = remotePeer.split(":"); InetSocketAddress remoteAddress = new InetSocketAddress(ar[0], Integer.parseInt(ar[1])); ChannelFuture channelFuture = boot.connect(remoteAddress).sync(); 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); connectionPoll.offer(channelFuture.channel()); connectionMap.put(remotePeer+"-"+index, channelFuture.channel()); } } }); }catch(Exception e){ LOGGER.error("connect to remote server. remote peer = " + remotePeer+" happen exception.", e); } } }