Learn Netty from scratch

Source: Internet
Author: User
Tags mixed
Learn Netty from scratch

In this chapter, we will look at the Netty from a 10,000-foot perspective. This will help you netty how the components are assembled together and why these are useful to you.
There are things that cannot be run without application (in Netty, they are the most important and common components we encounter). Bootstrap and Serverbootstrap EventLoop eventloopgroup channelpipeline Channel Future and Channelfuture Channelinitializer Channelhandler

These are the purposes of this chapter, the introduction of all these concepts to prepare for the rest of the book. We will describe how these components collaborate rather than introduce them separately, so that the assembly diagram of these components is built into your mind. Netty Quick Tutorials

Before we begin, it is useful to have a general understanding of the structure of the Netty (client and server-side structures are similar).
The Netty application begins with the bootstrap class, and Bootstrap is a constructor that makes it easy for Netty to configure the application's build and boot.
In order to allow multiple protocols and multiple methods of data processing, there are processors in the Netty. processors, as their names indicate, are designed to handle specific events or event groups in Netty. An event is a common way of describing it, for example, you have a processor that converts an object to byte, or vice versa; As you have a processor, exceptions are notified and processed during processing.
Realizing Channelinboundhandler is one of the most likely ways you can write. Channelinboundhandler receive data you can handle, and it's up to you to decide how to handle it. When your application needs to respond, you can write and scour the data in the Channelinboundhandler. In other words, your business logic is usually in Channelinboundhandler.


Business Logic


The business logic represents part of your program that processes data received from the network and converted to a certain format. This part of the code may be stored in a database, or something else. What you do depends entirely on your application, but it is usually the core of your application.

When Netty connects to the client or binds the server, it needs to know how to handle the data sent and received. This is done through different kinds of processors, but in Netty, Channelinitializer are used to configure these processors. The Channelinitializer task is to add the channelhandler of the implementation to the Channelpipeline. These processors determine how messages are processed when messages are sent and received. The Channelinitializer itself is Channelhandler, which removes itself from the channelpipeline after it has been added to the other processors.

All Netty applications are based on Channelpipeline. Channelpipeline is closely related to EventLoop and Eventloopgroup, and the three are related to event and event handling.
Emsp; The role of Eventloops in the application is to handle IO operations for the channel. A EventLoop event that typically handles multiple channels. The Eventloopgroup itself contains multiple eventloop that can be used to obtain a eventloop.
A channel represents a socket connection or some other component that can perform IO operations, so he is managed by EventLoop to handle IO tasks.

All IO operations in the Netty are performed asynchronously. For example, when you connect to a host, it is executed asynchronously by default. The same is true for writing and sending data. This means that the operation may not be executed directly, but picked up at some point in the later execution. Because of this, when an operation returns, you do not know if the operation is successful, but you need to check for success later, or you need a way to register the notification. To correct this problem, Netty uses future and channelfuture. This future can be used to register the listener, which is invoked when the operation succeeds or fails.


what Channelfuture is.


As previously emphasized, all IO operations in the Netty are asynchronous, and when you do it is not done directly, but at a later point in time. That's when channelfuture comes in handy. Channelfuture is a special java.util.concurrent.Future that allows you to register channnelfuturelisteners on channelfuture. These channnelfuturelisteners are triggered when the operation is complete.
So essentially speaking, channelfuture is a future operational result. It is hard to say because its execution depends on many facts. But one thing is for sure, it will be executed; All operations returning channelfuture that belong to the same channel are executed in the correct order, and the operations are executed in the same order. (Do not understand what the author wants to express, do not see clearly, please refer to the original
)

When you look at the other chapters, you will see that these concepts are repeatedly mentioned. The description may be more complex than this, and you can jump back here to read this simplified version again.

In the other parts of this chapter, we will expand the things we just talked about. channels, events, and IO

Netty is a non-blocking, event-driven network framework. In reality, this means that Netty uses threads to handle IO events. If you are familiar with multithreaded programming, you will tend to sync your code block. Absolutely unnecessary, Figure 3.1 shows why the Netty design makes it unnecessary to synchronize code blocks when handling Netty events.

Figure 3.1 Eventloopgroup and permanently bound to EventLoop channel

Figure 3.1 shows the Eventloopgroup owned by Netty, which have one or more eventloop. You can look at EventLoop as a thread that performs real work as a channel.


relationship between EventLoop and thread


EventLoop is always bound to a thread that does not change during the EventLoop lifecycle.

When a channel is registered, Netty binds the channel to a eventloop (also a thread), which is stored throughout the channel's lifecycle. This is why your application does not require synchronous Netty IO operations because all IO operations on one channel are handled by the same thread.
To illustrate these, figure 3.2 shows the relationship between EventLoop and Eventloopgroup.

Figure 3.2 Inheritance relationship of EventLoop and Eventloopgroup
The relationship between EventLoop and Eventloopgroup is not so intuitive because we said Eventloopgroup contains one or more eventloop, but as you can see from the diagram, EventLoop is actually eventloopgroup. This means that you can pass in the eventloop when you need to pass in the Eventloopgroup. Guide What. Why you need to boot.

Booting in Netty is the process of configuring your Netty application. You can use bootstrap when you need to connect the client to some host and port, or when the server is bound to the port. As implied in the previous life, there are two types of bootstrap that are used on the client, but also for Datagramchannel (Simple bootstrap), another server-side use (persistence serverbootstrap). Regardless of what protocol your application uses, the type of boot you use determines whether you are creating a client or server side.
These two types of bootstrap have a lot in common and actually have more in common than differences. Table 3.1 shows the key points and differences between the two.
Table 3.1 Similarities and differences between the two types

eventloopgroup number
same point bootstrap serverbootstrap
responsibilities connect to remote host and port bind to Port
1 2

The groups, transports, and processors are described separately in this chapter, and here we look at the key differences between the two types of bootstrap. The first difference is obvious, Serverboostrap is bound to the port because the server needs to listen for the connection, and bootstrap is used in either the client application or the Datagramchannel. Connect () is usually used in bootstrap, and of course you can call bind () and then use BIND () to return the channel connection in the Channelfuture.
The second difference may be the most important. The client bootstrap program uses 1 Eventloopgroup, while the server side uses 2 (actually two can be the same). It may not be clear for some time to do so, but it is reasonable. Serverbootstrap can be considered to have two sets of channels. The first group contains a socket that Serverchannel represents the server itself and is bound to a local port. The second group contains all the channels that the server accepts for the connection. Figure 3.3 Visualize both of these.

Figure 3.3 Differences between server and client groups
The sole purpose of eventloopgroup A in Figure 3.3 is to receive the connection and transfer it to Eventloopgroup B. Netty uses two different sets of groups because in some cases the application receives a significant number of connections, and a eventloopgroup can have bottlenecks because EventLoop is likely to be busy processing the received connection and may not be able to receive new connections in time. The resulting end result is some connection timeouts. By using two Eventloopgroup, all connections are accepted, even under very high load, because the eventloop of the receive connection and the EventLoop that handle the received connection are not shared.


Eventloopgroup and EventLoop


Eventloopgroup can contain more than 1 eventloop, depending on the configuration. Each channel is bound 1 eventloop when it is created, and this does not change. Because the number of eventloop contained in the Eventloopgroup may be less than the number of channels, many channels share 1 eventloop. This means that one channel in one eventloop is too busy to prevent other channels from processing. That's why you can't block the EventLoop.

Netty allows the use of the same eventloopgroup to process IO and receive connections. Many applications in production are running well. The process is illustrated in Figure 3.4.
Figure 3.4 shows the use of the same Eventloopgroup instance on the Netty server two times.

Figure 3.4 Netty Server configuration 1 eventloopgroup

In the next section, we'll discuss how netty and appropriate to perform IO operations. channel processors and data flow

We'll take a look at what happens when you're sending and receiving data. Recall the Netty processor concept we mentioned at the beginning of this chapter. In order to understand what happened to the data when it was written or read, we first need to understand what the processor is. The processor itself relies on the channelpipeline mentioned above to describe the order in which they are executed. So channelpipeline and processors are inseparable, it is not possible that only the processor is not channelpipeline, nor can it only be channelpipeline without any processor. Needless to say, we start with a processor, refer to ourselves, go into the other, and so forth. In the next sub section we will introduce Channelhandler and channelpipeline to make this cyclical dependency trivial. Channelpipeline and Handler

In most cases, the Channelhandler in Netty is the most in your application. Even if you are not aware of this, if you use Netty application, at least one channelhandler is involved. In other words, they are the key things. What the hell is it. It is not easy to give a definition of channelhandler, it should be so common that it can be considered to be any block of code that handles incoming and outgoing channelpipeline. There is actually an abstract interface Channelhandler for the processor. Both Channelinboundhandler and Channeloutboundhandler inherit from it, as shown in Figure 3.5. The

Figure 3.5 Channelhandler and its subclasses
is simple to illustrate Channelhandler from the point of view of the data flow of an example. Channelhandler can be applied in many ways, as you will see in the rest of this book.
The data flows in the Netty in two directions, showing the inflow processor (Channelinboundhandler) and the outgoing processor (Channeloutboundhandler) in Figure 3.5. Data from the user application to the distance is called outflow. The opposite data from the remote inflow application is called inflow.
Typically, data flows from one node to another, and one or more channelhandler manipulate the data in some way. These processors are added during the boot phase of the application. The order in which they are added determines the order in which they manipulate the data. The efficient arrangement for the specified order of the
Channelhandler is done by Channelpipeline. In other words, Channelpipeline is a set of channelhandler sorting combinations. Each channelhandler will process the data (if it can handle, for example, the flow of data only Channelinboundhandler can handle), The converted data is then passed to the next Channelhandler in the channelpipeline until there is no channelhandler.


Similarities between Channelhandler and servlet


In fact, the design in Netty is similar to that in the servlet. Channelhandler processes the data and passes the data to the next Channelhandler in Channelpipeline. Another common behavior is to pass the specified event to the next Channelhandler in the channelpipeline without any processing. This one channelhandler will process it and either transfer it to the next Channelhandler again.

Figure 3.6 shows the channelpipeline combination


Figure 3.6 Channelpipeline combination of examples
As shown in Figure 3.6, Channelinboundhandler and Channeloutboundhandler can be mixed together in the same channelpipeline.
In this channelpipeline, if a message is read or any other inflow event, it will start from the Channelpipeline's head and pass to the first Channelinboundhandler. This Channelinboundhandler handles this event, or does not process it, and then passes it on to the next Channelinboundhandler in Channelpipeline. Once there is no channelinboundhandler in the Channelpipeline, it arrives at Channelpipeline's tail, which means no more processing.
The reverse is also true, and any outflow event will start at the end of the Channelpipeline and pass to the last Channeloutboundhandler in Channelpipeline. Similar to an inflow process, it may or may not be processed, and then passed on to the next Channeloutboundhandler in Channelpipeline. The difference is that the next channeloutboundhandler here is actually the "previous one" because the outflow event is flowing from the tail of the channelpipeline to the head. Once no channeloutboundhandler can be passed, it reaches the transport layer and triggers some operations. For example, write operations.


base class of Channelinboundhandler and Channeloutboundhandler


An event can be passed to the channehandlercontext of the method to go to the next Channelinboundhandler or the previous channeloutboundhandler. Because these are the things you normally want to manipulate, we're not interested, so Netty provides the base class Channelinboundhandleradapter and Channeloutboundhandleradapter. These base classes provide implementations that use Channehandlercontext to pass events to the next or previous implementation in a method. You can override the method to do what you want to do.

You may suspect that the outflow and inflow operations are not the same, and how it works when the processor is mixed in the channelpipeline. Reference Figure 3.5, the inflow and outflow processors have different interfaces, all of which are extended channelhandler interfaces. This means that Netty can skip processors that are not of a particular type because the processors cannot handle the given operation. For example, an outflow event, Channelinboundhandler will be skipped because Netty knows whether each processor is channelinboundhandler or Channeloutboundhandler implementation.
Once a channelhandler is added to the Channelpipeline, the channelhandlercontext can be obtained. It is usually safe to obtain this reference and save it. This is not necessarily true when using message protocols such as UDP. This object can be used to get the underlying channel, which you typically save because you use it to write and send messages. This means that there are two ways to send messages in Netty, you can write directly to the channel or write to the Channelhandlercontext object. The difference between them is that the direct write channel causes the message to start at the end of the Channelpipeline, and writing the context object causes the message to start with the next processor in Channelpipeline. coding, decoding, and domain logic: further understanding of the processor

As we said earlier, there are all kinds of processors. Each one does what depends on the base class they inherit. Netty provides a range of adapter classes that make things simpler. Because in the pipeline, each processor is responsible for specifying the next processor in the Channelpipeline for the Netty event. With the adapter class, these are all done automatically, and you just need to override the method you're interested in. In addition to these adapter classes, there are classes that inherit from the adapter class to provide additional functionality, such as making encoding and decoding easier.


Adapter


There are some adapter classes that make it easier to write a channel processor. When you want to write a channel processor, it is recommended that you inherit an adapter class or encoding, decoding class (essentially inherited from the adapter class). There are some adapter classes in Netty: Channelhandleradapter channelinboundhandler channeloutboundhandler Channelduplexhandleradapter

Here we look at three special processor encodings, decoding and Simplechannelinboundhandler (it is a channelinboundhandleradapter subclass) Encoder, decoder

When you send or receive messages in Netty, messages must be converted from one form to another. If a message is received, it must be converted from a byte array to a Java object (decoded by some type of decoder). If you send a message, you must convert the Java entity to a byte array (encoded by some type of encoder). This conversion occurs frequently when data is sent over the network, because only byte arrays can be sent on the network.
There are different types of coding and decoding base classes that depend on your needs. For example, your application does not need to convert a message to a byte array immediately, but rather from a conversion to another message. An encoder is also needed, but different base classes are used. To know which base class is available, there is a little convention between the names of the base classes. In general, the name of the base class resembles Bytetomessagedecoder or Messagetobyteencoder. Some special types you will find Protobufencoder and Protobufdecoder, which are used to support the protocol cache that Google supports.
Strictly speaking, other processors can do things like encoders and decoders, but recall that depending on what you want to do there are different adapter classes. For decoders Channelinboundhandleradapter or Channelinboundhandler, all decoders are inherited or implemented. The "Channelread" method is overwritten, which is invoked when data is read from the inflow channel. The overridden Channelread method invokes the "Decode" method of each decoder, and by calling Channelhandlercontext.firechannelread (Decodedmessage) Passes the decoded message to the next Channelinboundhandler in the Channelpipeline.

When you send a message, something like this happens, except that the encoder converts the message to a byte array and passes it to the next channeloutboundhandler. Domain Logic

Perhaps one of the most common processors in your application is to receive decoded messages and do domain logic for this message. To create a processor like this, your application only needs to inherit the base class of Simplechannelinboundhandler, where T is the type that the processor can handle. In this processor, by covering a method of the base class, your application can get a channelhandlercontext reference, all of the methods pass the Channelhandlercontext as a parameter, and you can save it as a field in the class.
The main method involved in this processor is "channelRead0 (channelhandlercontext,t)". When Netty triggers this method, the T object is a message and your application can handle it. How you handle the message depends entirely on the need for your application. There is one thing to be aware of when processing messages, although there are multithreading in Netty to handle IO, your application should try not to block IO threads because of the performance problems in high concurrency.


Blocking Operations


As I said before, you must not block IO threads. This means there is a problem with blocking operations in the channel processor. Fortunately, there is a solution. Netty allows you to specify eventexecutorgroup when adding a channel processor. This eventexecutorgroup will be used to obtain a eventexecutor, which will perform all the methods of this event handler. This eventexecutor uses a completely different thread, thus relieving the eventloop pressure.
Summary

This chapter presents many of the concepts of Netty in a way that you understand how these things are assembled together. This means that later chapters will discuss them in detail in each chapter, where the relationship between the subject and the other components is not always clear. In this chapter, you browse the following topics bootstrap and Serverbootstrap EventLoop eventloopgroup channelpipeline Channel Future and Channelfuture Channelinitializer

Channelhandler and Sub Types

In later chapters, you will encounter these topics again, and they will be described in more detail.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.