一、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。