netty Learning Summary (I)
What is netty?
netty is an asynchronous, event-driven network programming framework.
Technical Foundation of netty
netty is an encapsulation of Java NIO and Java thread pool technology
What problems did netty solve
Using Java IO for network programming, usually one user and one thread, can not deal with a large number of users.
Using Java NIO for network programming, the programming complexity is too high. If there is no deep NIO network programming foundation, the program written may not be as good as the program written by Java IO.
As for Java AIO, it has not been clear which is better or worse than netty.
netty architecture
netty architecture is designed based on Reactor and responsibility chain model.
reactor
About the principle of reactor, reference“ [NIO Series]-Reactor Model"
The reactor of netty is a multi-reactor and multi-threaded model, in which reactor appears in the form of eventloop in netty.
Chain of Responsibility Model
netty assembles handlers through popeline, and listens for events that occur by adding handlers to the pipeline.
netty Server Programming Mode
// Evetloop pool for listening for client links, usually with only one eventloop NioEventLoopGroup bossGroup = new NioEventLoopGroup(); // Evetloop pool for handling client IO NioEventLoopGroup workGroup = new NioEventLoopGroup(); // Auxiliary classes to help initialize servers ServerBootStrap bootstrap = new ServerBootStrap(); bootstrap.group(bossGroup, workGroup) // bossGroup and workGroup can be the same .channel(NioServerSocketChannel.class) // Setting channel Type for Server-side Listening Sockets .option(ChannelOption.SO_BACKLOG, 1024) // Setting parameters for listening sockets .handler(new LoggingHandler()) // Setting handler for listening sockets .childHandler(new ChannelInitializer<SocketChannel>(){ // Setting handler for client socket public void initChannle(SocketChannel ch){ // Add handler to pipleline to handle client IO ch.pipeline().addLast(...); } }); int port = 8080; try{ ChannelFuture f = bootstrap.bind(port).sync(); f.channel().closeFuture().sync(); }catch(IOException e){ e.printStacktrac(); }finally{ bossGroup.shutdownGracefully(); workGroup.shutdownGracefully(); }
netty client programming model
// Evetloop pool for processing and server-side IO NioEventLoopGroup group = new NioEventLoopGroup(); // Auxiliary class to help initialize client BootStrap bootstrap = new BootStrap(); bootstrap.group(group) .channel(NioSocketChannel.class) // Setting channel Type of Client Socket .option(ChannelOption.NO_DELAY, true) // Setting parameters for client sockets .handler(new ChannelInitializer<SocketChannel>(){ // Setting handler for client socket public void initChannel(SocketChannel ch){ // Add handler to pipleline to handle client IO ch.pipeline().addLast(...); } }); String host = "127.0.0.1"; int port = 8080; try{ ChannelFuture f = bootstrap.connect(host, port).sync(); f.channel().closeFuture().sync(); }catch(IOException e){ e.printStacktrac(); }finally{ group.shutdownGracefully(); }
buffer
Netty thought Java NIO's Buffer was too hard to use, so he implemented a set of Buffers himself. Compared with Java NIO's netty buffer, it is not only easy to use, but also supports automatic expansion.
netty's buffer can be abstracted into three pointers: readIndex, writeIndex, limit.
Reading buffer increases read index, writing buffer increases write index, and if the amount of data written exceeds limit, buffer capacity increases. netty buffer also supports random reading and writing
Buffers in netty are generally created through Unpooled tool classes. There are three types of buffer s:
- The buffer allocated on the JVM heap. The advantage is fast allocation and easy recycling, but the disadvantage is that the data should be copied to the direct cache in the end.
- Direct buffer, which allocates memory directly through system call malloc, has the advantage of reducing data movement, but the disadvantage is slow allocation and troublesome recovery.
- Composite buffers, which encapsulate different types of buffers, are like accessing a buffer. Buffers can be partitioned in this way, but access time is increased.
handler
Handler is divided into handler dealing with inbound events and handler dealing with outbound events. Listen for events by implementing appropriate methods
netty also provides adapter classes to reduce developers'workload.
Inbound handler
Inbound events are generally triggered externally, such as receiving data.
Base class is ChannelInboundHandler
Out-of-stack handler
Outbound events are triggered internally, such as writing data
Base class is ChannelOutboundHandler