limax网络开启-Engine

NIO网络连接

1.启动入口

public void startNetEngine() throws Exception {
    runTaskBeforeEngineStart();
    startNetEngineByThreadPoolSizeInfo();
    runTaskAfterEngineStart();
}

2.runTaskBeforeEngine与runTaskAfterEngine任务

(1)runTaskBeforeEngine:

  • Service.addRunBeforeEngineStartTask(() -> Zdb.getInstance().start(meta));

(2)runTaskAfterEngineStart:

  • Engine.getProtocolScheduler().scheduleAtFixedRate(() -> load(path), 0,
    period, TimeUnit.MILLISECONDS)

  • () -> {
    try {
    final InetSocketAddress sa = new InetSocketAddress(httpServerIp, httpServerPort);
    final HttpServer server = HttpServer.create(sa, 0);
    server.setExecutor(ConcurrentEnvironment.getInstance().newThreadPool(“limax.auany.httpServer”,
    httpServerPool));
    httphandlers.forEach((context, handler) -> server.createContext(context, handler));
    server.start();
    Service.addRunBeforeEngineStopTask(() -> {
    server.stop(0);
    ConcurrentEnvironment.getInstance().shutdown(“limax.auany.httpServer”);
    });
    } catch (Exception e) {
    if (Trace.isErrorEnabled())
    Trace.error(“start httpServer”, e);
    }
    });

  • () -> launchManagerTask(builder.dispatcher(new Dispatcher(Engine.getProtocolExecutor())),
    GlobalIdListener.getInstance(), self.getAttribute(“name”))

  • () -> launchManagerTask(
    builder.dispatcher(new Dispatcher(Engine.getProtocolExecutor())), listener, name)

  • () -> {
    Thread thread = new Thread(() -> {
    try {
    limax.node.js.Main.launchEngine(module, parameters);
    } catch (Exception e) {
    if (Trace.isErrorEnabled())
    Trace.error(“Load Node module: ” + module, e);
    }
    });
    thread.setDaemon(true);
    thread.start();
    }

3.开启网络Engine.open

public static void open(int nioCpus, int netProcessors, int protocolSchedulers, int applicationExecutors) throws Exception {
    if (netProcessors < 1 || protocolSchedulers < 1 || applicationExecutors < 1 || nioCpus < 1)
        throw new IllegalArgumentException("any engine parameter must > 0");
    lock.lock();
    try {
        if (!closed)
            throw new IllegalStateException("engine is not closed!");
        NetModel.initialize(new FixedCpuPoll(nioCpus), netProcessors);
        ConcurrentEnvironment env = ConcurrentEnvironment.getInstance();
        engineExecutor = new Dispatcher(env.newThreadPool("limax.net.Engine.applicationExecutor", 0));
        applicationExecutor = env.newHashExecutor("limax.net.Engine.applicationExecutor", applicationExecutors);
        protocolScheduler = env.newScheduledThreadPool("limax.net.Engine.protocolScheduler", protocolSchedulers);
        protocolExecutor = env.newHashExecutor("limax.net.Engine.protocolScheduler", protocolSchedulers);
        closed = false;
    } finally {
        lock.unlock();
    }
}

NetModel包括FixedCapacityPoll和FixedCPUPoll两种策略,由NetModel.initialize初始化

public static void initialize(PollPolicy pp, int processPoolSize) throws IOException, JMXException {
    ConcurrentEnvironment env = ConcurrentEnvironment.getInstance();
    pollPolicy = pp;
    env.newFixedThreadPool("limax.net.io.NetModel.processPool", processPoolSize);
    processPool = env.newHashExecutor("limax.net.io.NetModel.processPool", processPoolSize * 16);
    delayPool = env.newScheduledThreadPool("limax.net.io.NetModel.delayPool", delayPoolSize);
    mbeans = MBeans.register(MBeans.root(), new TaskStateMXBean() {
        public long getTotal() {
            return NetTaskImpl.total.longValue();
        }

        public long getRunning() {
            return NetTaskImpl.running.longValue();
        }

        public List<Integer> getPollTaskSize() {
            return pollPolicy.q.stream().map(PollTask::size).collect(Collectors.toList());
        }
    }, "limax.net.io:type=NetModel,name=TaskState");
}

4.runTaskAfterEngineStart中会开启client,server网络连接

public static ServerContext addServer(SocketAddress sa, int backlog, int rsize, int wsize,
        ServerContext.NetTaskConstructor constructor, boolean autoOpen) throws IOException {
    ServerContextImpl context = new ServerContextImpl(sa, backlog, rsize, wsize, constructor);
    if (autoOpen)
        context.open();
    return context;
}

public static void addClient(SocketAddress sa, NetTask task) throws IOException {
    SocketChannel sc = SocketChannel.open();
    sc.configureBlocking(false);
    sc.connect(sa);
    pollPolicy.addChannel(sc, SelectionKey.OP_CONNECT, task);
}

其中ServerContextImpl.open()

public synchronized void open() throws IOException {
    if (closed) {
        channel = ServerSocketChannel.open();
        channel.configureBlocking(false);
        channel.socket().setReuseAddress(true);
        channel.socket().bind(sa, backlog);
        //注册Selector事件
        NetModel.pollPolicy.addChannel(channel, SelectionKey.OP_ACCEPT, this);
        closed = false;
    }
}

5.PollTask中抽象了NIO连接过程

class PollTask implements Runnable, Comparable<PollTask> {
private final Selector sel;
private volatile boolean closed;
private volatile int size;

int size() {
    return size;
}

@Override
public int compareTo(PollTask op) {
    return size - op.size();
}

PollTask() throws IOException {
    this.sel = Selector.open();
}

synchronized SelectionKey register(SelectableChannel ch, int ops, Object att) throws ClosedChannelException {
    return ch.register(sel.wakeup(), ops, att);
}

void close() {
    closed = true;
    sel.wakeup();
}

private void doAccept(SelectionKey key) throws IOException {
    ServerContextImpl context = (ServerContextImpl) key.attachment();
    NetOperation op = context.newInstance();
    SocketChannel channel = ((ServerSocketChannel) key.channel()).accept();
    channel.configureBlocking(false);
    op.attachKey(NetModel.pollPolicy.addChannel(channel, 0, op));
}

private void doConnect(SelectionKey key) throws IOException {
    NetOperation op = (NetOperation) key.attachment();
    SocketChannel channel = (SocketChannel) key.channel();
    if (!channel.finishConnect())
        throw new IOException("impossibly, channel's socket is NOT connected");
    op.attachKey(key.interestOps(0));
}

private void doRead(SelectionKey key) throws IOException {
    NetOperation op = (NetOperation) key.attachment();
    SocketChannel channel = (SocketChannel) key.channel();
    ByteBuffer rbuf = op.getReaderBuffer();
    synchronized (rbuf) {
        if (channel.read(rbuf) == -1)
            throw new IOException("the channel has reached end-of-stream");
        if (!rbuf.hasRemaining()) {
            key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
            op.onReadBufferEmpty();
        }
    }
}

private void doWrite(SelectionKey key) throws IOException {
    NetOperation op = (NetOperation) key.attachment();
    SocketChannel channel = (SocketChannel) key.channel();
    Queue<ByteBuffer> vbuf = op.getWriteBuffer();
    synchronized (vbuf) {
        op.bytesSent(channel.write(vbuf.toArray(new ByteBuffer[0])));
        while (!vbuf.isEmpty() && !vbuf.peek().hasRemaining())
            vbuf.poll();
        if (vbuf.isEmpty()) {
            if (op.isFinalInitialized()) {
                op.setFinal();
                throw new IOException("channel closed manually");
            }
            key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
            op.onWriteBufferEmpty();
        }
    }
}

private void doClose(SelectionKey key, Throwable e) {
    Object att = key.attachment();
    if (att instanceof NetOperation)
        ((NetOperation) att).close(e);
    else if (att instanceof ServerContextImpl)
        try {
            ((ServerContextImpl) att).close();
        } catch (IOException e1) {
        }
}

//处理网络的线程池
@Override
public final void run() {
    try {
        synchronized (this) {
        }
        sel.selectedKeys().clear();
        sel.select();
        for (SelectionKey key : sel.selectedKeys()) {
            try {
                if (key.isAcceptable()) {
                    try {
                        doAccept(key);
                    } catch (Throwable e) {
                    }
                } else if (key.isConnectable()) {
                    try {
                        doConnect(key);
                    } catch (Throwable e) {
                        doClose(key, e);
                    }
                } else {
                    Throwable catched = null;
                    boolean needsche = false;
                    if (key.isReadable()) {
                        try {
                            doRead(key);
                            needsche = true;
                        } catch (Throwable e) {
                            catched = e;
                        }
                    }
                    if (key.isWritable()) {
                        try {
                            doWrite(key);
                            needsche = true;
                        } catch (Throwable e) {
                            if (catched == null)
                                catched = e;
                        }
                    }
                    if (catched != null)
                        doClose(key, catched);
                    else if (needsche)
                        ((NetOperation) key.attachment()).schedule();
                }
            } catch (CancelledKeyException e) {
            }
        }
    } catch (Throwable e) {
        if (Trace.isDebugEnabled())
            Trace.debug("limax.net.io.PollTask", e);
    } finally {
        if (closed) {
            IOException e = new IOException("channel closed manually");
            for (SelectionKey key : sel.keys())
                doClose(key, e);
            try {
                sel.close();
            } catch (IOException e1) {
            }
        } else {
            size = sel.keys().size();
            NetModel.pollPolicy.schedule(this);
        }
    }
}

}

6.总结:

(1)在接收消息时注册了StateTransportImpl,用于input,output coderc

(2)Engine.open()中配置了开启网络线程数

(3)网络,定时器,任务线程池包含:

engineExecutor = new Dispatcher(env.newThreadPool("limax.net.Engine.applicationExecutor", 0));
applicationExecutor = env.newHashExecutor("limax.net.Engine.applicationExecutor", applicationExecutors);
protocolScheduler = env.newScheduledThreadPool("limax.net.Engine.protocolScheduler", protocolSchedulers);
protocolExecutor = env.newHashExecutor("limax.net.Engine.protocolScheduler", protocolSchedulers);

(4)网络联通后下一个过程是网络协议的解析与加密问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值