Home >Java >javaTutorial >What is Netty? In-depth analysis of Netty related knowledge

What is Netty? In-depth analysis of Netty related knowledge

不言
不言forward
2018-11-24 16:22:323192browse

This article brings you what is Netty? The in-depth analysis of Netty related knowledge has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

What is Netty

Start with HTTP

With Netty, you can implement your own HTTP server, FTP server, UDP server, RPC server, WebSocket server, Redis Proxy server, MySQL Proxy server, etc.

Let’s review the principles of traditional HTTP servers

1. Create a ServerSocket, listen and bind a port

2. A series of clients request this port

3. The server uses Accept to obtain a Socket connection object from the client

4. Start a new thread to process the connection

4.1. Read the Socket and obtain the byte stream

4.2. Decode the protocol and get the Http request object

4.3. Process the Http request and get a result and encapsulate it into an HttpResponse object

4.4. Encode the protocol and serialize the result into words Throttle write Socket and send the byte stream to the client

5. Continue to cycle step 3

The reason why the HTTP server is called an HTTP server is because the encoding and decoding protocol is the HTTP protocol. If If the protocol is the Redis protocol, then it becomes a Redis server, if the protocol is WebSocket, then it becomes a WebSocket server, and so on. Using Netty, you can customize the encoding and decoding protocol and implement your own protocol-specific server.

NIO

The above is a traditional HTTP server, but in a high-concurrency environment, the number of threads will be larger and the system load will be higher, so NIO is created.

He is not a concept unique to Java. A term represented by NIO is called IO multiplexing. It is a system call provided by the operating system. In the early days, the name of this operating system call was select, but its performance was low. It later gradually evolved into epoll under Linux and kqueue in Mac. We generally call it epoll, because no one uses Apple computers as servers to provide external services. Netty is a framework based on Java NIO technology. Why encapsulation is necessary? Because native Java NIO is not that convenient to use and has notorious bugs. After Netty encapsulates it, it provides an easy-to-operate usage mode and interface, which makes it much more convenient for users to use.

Before talking about NIO, let’s talk about BIO (Blocking IO). How to understand this Blocking?

When the client is listening (Listen), Accept is blocked. Only when a new connection comes, Accept will return and the main thread can continue

When reading and writing the socket, Read is blocked. Only when the request message comes, can Read return and the sub-thread can continue to process

When reading and writing the socket, Write is blocked. Only when the client receives the message can Write return and the sub-thread can continue reading. A request

In the traditional BIO mode, all threads are blocked from beginning to end. These threads just wait, occupying system resources, and do nothing.

So how does NIO achieve non-blocking? It uses an event mechanism. It can use one thread to do all the logic of Accept, read and write operations, and request processing. If there is nothing to do, it will not loop endlessly. It will sleep the thread until the next event comes and then continue working. Such a thread is called a NIO thread. Expressed in pseudo code:

while true {

    events = takeEvents(fds)  // 获取事件,如果没有事件,线程就休眠

    for event in events {        if event.isAcceptable {

            doAccept() // 新链接来了
        } elif event.isReadable {

            request = doRead() // 读消息

            if request.isComplete() {

                doProcess()

            }

        } elif event.isWriteable {

            doWrite()  // 写消息
        }

    }

}

Reactor thread model

Reactor single-thread model

One NIO thread and one accept thread:

What is Netty? In-depth analysis of Netty related knowledge

Reactor multi-threading model

What is Netty? In-depth analysis of Netty related knowledge

##Reactor master-slave model

Master-slave Reactor multi-threading: multiple acceptor NIO thread pools are used to accept client connections

What is Netty? In-depth analysis of Netty related knowledge

Netty can be flexibly configured based on the above three models.

Summary

Netty is built on NIO, and Netty provides a higher level of abstraction on top of NIO.

In Netty, Accept connections can be handled by a separate thread pool, and read and write operations are handled by another thread pool.

Accept连接和读写操作也可以使用同一个线程池来进行处理。而请求处理逻辑既可以使用单独的线程池进行处理,也可以跟放在读写线程一块处理。线程池中的每一个线程都是NIO线程。用户可以根据实际情况进行组装,构造出满足系统需求的高性能并发模型。

为什么选择Netty

如果不用netty,使用原生JDK的话,有如下问题:

1、API复杂

2、对多线程很熟悉:因为NIO涉及到Reactor模式

3、高可用的话:需要出路断连重连、半包读写、失败缓存等问题

4、JDK NIO的bug

而Netty来说,他的api简单、性能高而且社区活跃(dubbo、rocketmq等都使用了它)

什么是TCP 粘包/拆包

现象

先看如下代码,这个代码是使用netty在client端重复写100次数据给server端,ByteBuf是netty的一个字节容器,里面存放是的需要发送的数据

public class FirstClientHandler extends ChannelInboundHandlerAdapter { 
 @Override 
 public void channelActive(ChannelHandlerContext ctx) { 
 for (int i = 0; i < 1000; i++) { 
 ByteBuf buffer = getByteBuf(ctx); 
 ctx.channel().writeAndFlush(buffer); 
 } 
 } 
 private ByteBuf getByteBuf(ChannelHandlerContext ctx) { 
 byte[] bytes = "需要更多资料加群:586446657".getBytes(Charset.forName("utf-8")); 
 ByteBuf buffer = ctx.alloc().buffer(); 
 buffer.writeBytes(bytes); 
 return buffer; 
 }
}

从client端读取到的数据为:

What is Netty? In-depth analysis of Netty related knowledge

从服务端的控制台输出可以看出,存在三种类型的输出

一种是正常的字符串输出。

一种是多个字符串“粘”在了一起,我们定义这种 ByteBuf 为粘包。

一种是一个字符串被“拆”开,形成一个破碎的包,我们定义这种 ByteBuf 为半包。

透过现象分析原因

应用层面使用了Netty,但是对于操作系统来说,只认TCP协议,尽管我们的应用层是按照 ByteBuf 为 单位来发送数据,server按照Bytebuf读取,但是到了底层操作系统仍然是按照字节流发送数据,因此,数据到了服务端,也是按照字节流的方式读入,然后到了 Netty 应用层面,重新拼装成 ByteBuf,而这里的 ByteBuf 与客户端按顺序发送的 ByteBuf 可能是不对等的。因此,我们需要在客户端根据自定义协议来组装我们应用层的数据包,然后在服务端根据我们的应用层的协议来组装数据包,这个过程通常在服务端称为拆包,而在客户端称为粘包。

拆包和粘包是相对的,一端粘了包,另外一端就需要将粘过的包拆开,发送端将三个数据包粘成两个 TCP 数据包发送到接收端,接收端就需要根据应用协议将两个数据包重新组装成三个数据包。

如何解决

在没有 Netty 的情况下,用户如果自己需要拆包,基本原理就是不断从 TCP 缓冲区中读取数据,每次读取完都需要判断是否是一个完整的数据包 如果当前读取的数据不足以拼接成一个完整的业务数据包,那就保留该数据,继续从 TCP 缓冲区中读取,直到得到一个完整的数据包。 如果当前读到的数据加上已经读取的数据足够拼接成一个数据包,那就将已经读取的数据拼接上本次读取的数据,构成一个完整的业务数据包传递到业务逻辑,多余的数据仍然保留,以便和下次读到的数据尝试拼接。

而在Netty中,已经造好了许多类型的拆包器,我们直接用就好:

What is Netty? In-depth analysis of Netty related knowledge

选好拆包器后,在代码中client段和server端将拆包器加入到chanelPipeline之中就好了:

如上实例中:

客户端:

ch.pipeline().addLast(new FixedLengthFrameDecoder(31));

服务端:

ch.pipeline().addLast(new FixedLengthFrameDecoder(31));

What is Netty? In-depth analysis of Netty related knowledge

Netty 的零拷贝

传统意义的拷贝

是在发送数据的时候,传统的实现方式是:

1. `File.read(bytes)`

2. `Socket.send(bytes)`

这种方式需要四次数据拷贝和四次上下文切换:

1. 数据从磁盘读取到内核的read buffer

2. 数据从内核缓冲区拷贝到用户缓冲区

3. 数据从用户缓冲区拷贝到内核的socket buffer

4. 数据从内核的socket buffer拷贝到网卡接口(硬件)的缓冲区

零拷贝的概念

明显上面的第二步和第三步是没有必要的,通过java的FileChannel.transferTo方法,可以避免上面两次多余的拷贝(当然这需要底层操作系统支持)

1. Call transferTo, the data is copied from the file to the kernel read buffer by the DMA engine

2. Then DMA copies the data from the kernel read buffer to the network card interface buffer

Two times above The operation does not require CPU participation, so zero copy is achieved.

Zero copy in Netty

is mainly reflected in three aspects:

1. bytebuffer

Netty mainly uses bytebuffer to send and receive messages, and bytebuffer is used External memory (DirectMemory) directly reads and writes Socket.

Reason: If traditional heap memory is used for Socket reading and writing, the JVM will copy the heap memory buffer to direct memory and then write it to the socket, creating an additional memory copy of the buffer. DirectMemory can be sent directly to the network card interface through DMA

2. Composite Buffers

Traditional ByteBuffer, if you need to combine the data in two ByteBuffers together, we need to first create a size= Create a new array of size1 size2, and then copy the data in the two arrays to the new array. However, using the combined ByteBuf provided by Netty, you can avoid such operations, because CompositeByteBuf does not really combine multiple Buffers, but saves their references, thus avoiding data copying and achieving zero copy.

3. The use of FileChannel.transferTo

Netty uses the transferTo method of FileChannel, which relies on the operating system to implement zero copy.

Netty internal execution process

Server:

What is Netty? In-depth analysis of Netty related knowledge

What is Netty? In-depth analysis of Netty related knowledge

##1. Create a ServerBootStrap instance

2. Set up and bind the Reactor thread pool: EventLoopGroup. EventLoop is to process all Channels on the Selector registered to this thread

3. Set up and bind the channel on the server

4.5. Create a ChannelPipeline and handler to handle network events. Network time flows through it in the form of a stream. The handler completes most of the function customization: such as editing Decode SSl security authentication

6. Bind and start the listening port

7. When the ready channel is polled, the Reactor thread: NioEventLoop executes the method in the pipline, and finally schedules and executes it. channelHandler

8. Speaking of which, I would like to recommend a Java communication and learning community: 586446657, where you can not only communicate and discuss, but also share interview experience and download free materials, including Spring, MyBatis, and Netty source code analysis. , the principles of high concurrency, high performance, distributed, microservice architecture, and JVM performance optimization have become a necessary knowledge system for architects. I believe that for coders who are already working and encounter technical bottlenecks, there will be the content you need here.

Client

What is Netty? In-depth analysis of Netty related knowledge

What is Netty? In-depth analysis of Netty related knowledge

##Summary

The above is I have compiled some knowledge related to Netty. If you have different opinions, please feel free to discuss!

The above is the detailed content of What is Netty? In-depth analysis of Netty related knowledge. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:cnblogs.com. If there is any infringement, please contact admin@php.cn delete