netty source code analysis (xviii) Netty underlying system architecture and application practice summary

  1. A EventLoopGroup which contains one or more EventLoop.
  2. A EventLoop will only be bound to a single Thread in which its entire life cycle.
  3. All the various I processed by the EventLoop / O events will be processed on the Thread which it is associated.
  4. A Channel throughout its life cycle will only be registered on a EventLoop.
  5. A EventLoop during operation, will be assigned to one or a plurality of Channel.
  6. Execution order and submitted the order with the task of submitting a Channel is the same (Advanced to go out first, the task queue).

Important conclusion: in the realization of netty of which must be thread-safe, based on this we can be a channel of reference memory storage, and when you need to send data to the remote endpoint, by this reference to call the appropriate Channel method; even though there were many threads it also does not appear in the use of multi-threading issues, and the message will be sent out in the order.

Important conclusion: time-consuming tasks in our business development, not to put the long-running execution queue EventLoop, since it will have to block all other tasks on the Channel corresponding to the thread, if we need to blocking calls or time-consuming operation (the actual development are common), then we need to use a special EventExecutor (business thread pool).

Usually we have two kinds of ways:
1, in ChannelHandler callback method, using a thread pool their definition of business, so that you can achieve asynchronous calls.
Write pictures described here
2, by means of the methods to be invoked addLast ChannelHandler added to ChannelPipeLine netty provided to pass EventExecutor.
Note: By default (call addLast (handler)), in ChannelHandler callback method is performed by the I / O thread, if you call ChannelPipeline addLast (EventExecutorGroup group, ChannelHandler ... handlers); method, then ChannelHandler callback method It is performed by parameter group thread group.
Write pictures described here

netty asynchronous:
Write pictures described here

You can see from the chart, ChannelPromise inherited the Promise interface, Promise can write (writable), what can be written, before the Future are get, isSuccess method and the like, can be seen in ChannelPromise inside setSuccess ( void result) [setSuccess can be written only once, the next time an error writing] write method and the like. ChannelPromise literally means commitment, regardless of success or failure would promise to give you a result.

Future JDK provided only by manually checking the implementation of the results, and this operation will be blocked; Netty is to ChannelFuture been enhanced, here is related to the observer mode to execute the callback way to get results ChannelFutureListener, in addition to the operating manual inspection obstruction, it is worth noting that: operationcomplete ChannelFutureListener method is performed by the I / O thread, so pay attention to is not to perform time-consuming operations here, or need required by another thread or thread pool carried out.
Write pictures described here
For example: jdk's Future returns the results obtained using isDone get or acquire, and these two are blocking the way, even if the method timeout time to also get less return null, these things are developers to do their own while Netty solved the drawbacks, netty by adding the listener mode on the Future, registration number Listner to the Future, Future hold Channel, when a particular event occurs, Future Listner call the corresponding method, the method participants have a reference to the current Future, we will get in the Channel Future Listener inside, after obtaining the data is processed in the Channel Listener inside, which is the method Listener not to say inside the top reasons for handling time-consuming business.

To tell you the ChannelHandler, ChannelHandler have pushed and popped the Handler, took ChannelInboundHandlerAdapter, we want to write a stack processors, you need all the methods inside interfaces must be rewritten, but we only use part of the method, and the Adapter is a kind of adapter mode, all methods will achieve, when we use the direct use of the adapted category (either directly or rewritten) to implement business logic on it, greatly facilitate and reduce the developer to the developer's work the amount.

1
2
3
4
5
6
7
8
9
10
11
12
public class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter implements ChannelInboundHandler {
...略
public ChannelInboundHandlerAdapter() {
}
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelRegistered();
}
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
ctx.fireChannelUnregistered();
}
...略
}

ChannelInboundHandlerAdapter concrete implementation class has SimpleChannelInboundHandler, he and ChannelInboundHandlerAdapter What difference does it make?

. 1 
2
. 3
. 4
. 5
. 6
. 7
. 8
. 9
10
. 11
12 is
13 is
14
15
16
. 17 large column  netty source analysis (xviii) Netty underlying architecture summary and Application of System
18 is
. 19
20 is
21 is
22 is
23 is
24
25
26 is
27
abstract class SimpleChannelInboundHandler public <the I> the extends ChannelInboundHandlerAdapter 
{
... slightly
protected abstract void channelRead0 (ChannelHandlerContext ctx, the I msg) throws Exception;
// developer must implement this method, because it is static (template design mode)
... a little

void channelRead public (ChannelHandlerContext CTX, Object MSG) throws Exception {
Boolean = Release to true;
the try {
IF (acceptInboundMessage (MSG)) {
@SuppressWarnings ( "an unchecked")
the I IMSG = (the I) MSG; // cast
channelRead0 (ctx , imsg); // developer exposed to the interface with generic
} the else {
Release = to false;
ctx.fireChannelRead (MSG);
}
} the finally {
IF (autorelease && Release) {
ReferenceCountUtil.release (MSG); / / reference number minus one, the freed resources, a reference to the message that we do not peripheral reference
// because the message is released out here
}
}
}

}

It is intuitive that the addition of a generic I, Type I is to accept the message, such as String, Object, etc., while in ChannelInboundHandlerAdapter inside four messages need to be cast, which is their biggest difference. In addition SimpleChannelInboundHandler message will perform ReferenceCountUtil.release (Object) and ReferenceCountUtil.retain (Object), respectively release a message reference and to maintain a message reference (flow to the next handler).
We generally use ChannelInboundHandlerAdapter and processing into SimpleChannelInboundHandler stack data.
Practical application:
Write pictures described here

ReferenceCountUtil method of release:

1
2
3
4
5
6
public static boolean release(Object msg) {
if (msg instanceof ReferenceCounted) {
return ((ReferenceCounted) msg).release();
}
return false;
}

ReferenceCounted used is the class of operation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* A reference-counted object that requires explicit deallocation.
* <p>
* When a new {@link ReferenceCounted} is instantiated, it starts with the reference count of {@code 1}.
* {@link #retain()} increases the reference count, and {@link #release()} decreases the reference count.
* If the reference count is decreased to {@code 0}, the object will be deallocated explicitly, and accessing
* the deallocated object will usually result in an access violation.
* </p>
* 当一个ReferenceCounted被实例化的时候,它的引用数是1,retain()增加一个引用次数,release()减少一个引用次数,如果引用数量是0
* 的时候,这个对象将会被显示的回收,去访问的一个被回收的对象通常的结果是访问违法常规的。
* <p>
* If an object that implements {@link ReferenceCounted} is a container of other objects that implement
@Link ReferenceCounted} {*, The Will Also Contained Objects BE Via Released @link #RELEASE {()} The Container When apos
* Becomes COUNT of 0. The Reference
* </ P>
* If an object that implements a class most a ReferenceCounted container, and the container inside a number of objects, then the number of times the outer container is referenced to zero time, as the recovery vessel,
* objects inside of the container will be recovered.
* /
Public interface ReferenceCounted {
.... slightly
}

Guess you like

Origin www.cnblogs.com/lijianming180/p/12032670.html