在zk模板配置文件中有:
# the maximum number of client connections. # increase this if you need to handle more clients maxClientCnxns=60
这个配置的作用就是:一个ip所对应的客户机,只能和zk服务器维持60个连接。
以NIOServerCnxnFactory为例:
public abstract class ServerCnxnFactory { //存放zk所有连接 protected final HashSet<ServerCnxn> cnxns = new HashSet<ServerCnxn>(); } public class NIOServerCnxnFactory extends ServerCnxnFactory implements Runnable { //客户端ip -> 客户端的连接集合 final HashMap<InetAddress, Set<NIOServerCnxn>> ipMap = new HashMap<InetAddress, Set<NIOServerCnxn>>( ); //获取指定ip的连接数 private int getClientCnxnCount(InetAddress cl) { // The ipMap lock covers both the map, and its contents // (that is, the cnxn sets shouldn't be modified outside of // this lock) synchronized (ipMap) { Set<NIOServerCnxn> s = ipMap.get(cl); if (s == null) return 0; return s.size(); } } public void run() { while (!ss.socket().isClosed()) { try { selector.select(1000); Set<SelectionKey> selected; synchronized (this) { selected = selector.selectedKeys(); } ArrayList<SelectionKey> selectedList = new ArrayList<SelectionKey>( selected); Collections.shuffle(selectedList); for (SelectionKey k : selectedList) { if ((k.readyOps() & SelectionKey.OP_ACCEPT) != 0) { SocketChannel sc = ((ServerSocketChannel) k .channel()).accept(); InetAddress ia = sc.socket().getInetAddress(); //获取客户端连接数 int cnxncount = getClientCnxnCount(ia); //单个客户端连接数超过限制 if (maxClientCnxns > 0 && cnxncount >= maxClientCnxns){ LOG.warn("Too many connections from " + ia + " - max is " + maxClientCnxns ); sc.close(); } else { LOG.info("Accepted socket connection from " + sc.socket().getRemoteSocketAddress()); sc.configureBlocking(false); SelectionKey sk = sc.register(selector, SelectionKey.OP_READ); NIOServerCnxn cnxn = createConnection(sc, sk); sk.attach(cnxn); addCnxn(cnxn); } } else if ((k.readyOps() & (SelectionKey.OP_READ | SelectionKey.OP_WRITE)) != 0) { NIOServerCnxn c = (NIOServerCnxn) k.attachment(); c.doIO(k); } else { if (LOG.isDebugEnabled()) { LOG.debug("Unexpected ops in select " + k.readyOps()); } } } selected.clear(); } catch (RuntimeException e) { LOG.warn("Ignoring unexpected runtime exception", e); } catch (Exception e) { LOG.warn("Ignoring exception", e); } } closeAll(); LOG.info("NIOServerCnxn factory exited run method"); } }
tips: 关心这个参数,是因为之前有人上线时,客户端连接数超过了默认值,导致无法建立连接。