一、Reactor模型java
一、单线程Reactorreact
二、线程池Reactorgit
一、一个线程专门处理accecpt(),该线程还处理SSL握手等,由于该线程的压力很大,回是瓶颈。github
三、主从Reactor异步
一、主reactor用于accept(包含SSL握手和验证,登陆等)tcp
二、从reactoride
用于处理其余事件spa
二、线程模型:操作系统
netty的handler处理是在IO线程里运行的。若是本身的业务很小,能够不在handler里面使用本身的线程池,若是本身的业务很费时间,须要使用本身的线程池进行异步处理。线程
三、Netty的启动,写API都是异步的。
四、 ctx.write(msg);也是异步的,内部实现多是将bytebuffer放进netty本身的缓冲队列里,而没有提交给tcp缓冲区。
ctx.writeAndFlush(time);
这个方法会走到下面的代码:能够看出Netty对于NIO写的处理是只循环写16次,若是还没写完则不继续写了。使用NIO的写逻辑都应该是这样不断的循环写吧。
IO写应该先在本身的缓冲区缓冲足够的数据,而后再调操做系统API写(一方面调操做系统API须要不断在内核态和用户态切换,另外一方面对介质的写操做应该是一次提交大量的数据,而不是小量的 数据,这能提升效率)。
protected void doWrite(ChannelOutboundBuffer in) throws Exception { for (;;) { int size = in.size(); if (size == 0) { // All written so clear OP_WRITE clearOpWrite(); break; } long writtenBytes = 0; boolean done = false; boolean setOpWrite = false; // Ensure the pending writes are made of ByteBufs only. ByteBuffer[] nioBuffers = in.nioBuffers(); int nioBufferCnt = in.nioBufferCount(); long expectedWrittenBytes = in.nioBufferSize(); SocketChannel ch = javaChannel(); // Always us nioBuffers() to workaround data-corruption. // See https://github.com/netty/netty/issues/2761 switch (nioBufferCnt) { case 0: // We have something else beside ByteBuffers to write so fallback to normal writes. super.doWrite(in); return; case 1: // Only one ByteBuf so use non-gathering write ByteBuffer nioBuffer = nioBuffers[0];
//由于采起的是NIO,因此一次写可能写不完。默认是循环写16次,若是还没写完,则返回。 for (int i = config().getWriteSpinCount() - 1; i >= 0; i --) { final int localWrittenBytes = ch.write(nioBuffer); if (localWrittenBytes == 0) { setOpWrite = true; break; } expectedWrittenBytes -= localWrittenBytes; writtenBytes += localWrittenBytes; if (expectedWrittenBytes == 0) { done = true; break; } } break; default: for (int i = config().getWriteSpinCount() - 1; i >= 0; i --) { final long localWrittenBytes = ch.write(nioBuffers, 0, nioBufferCnt); if (localWrittenBytes == 0) { setOpWrite = true; break; } expectedWrittenBytes -= localWrittenBytes; writtenBytes += localWrittenBytes; if (expectedWrittenBytes == 0) { done = true; break; } } break; } // Release the fully written buffers, and update the indexes of the partially written buffer. in.removeBytes(writtenBytes); if (!done) { // Did not write all buffers completely. incompleteWrite(setOpWrite); break; } } }
五、netty的解码器在处理数据时可能会缓冲不少的数据,直到复合一个报文要求才会将缓冲的数据提交给下一个handler。