Netty Reliability Design One

Source: Internet
Author: User

NiO Chat

Since JAVA1.4 launched NIO, Java Network programming into a completely new era, the traditional network IO (OIO) is a silly equation, once the IO operation initiated, then the user thread into a silly very naïve wait until the IO operation is over or a break-even, and NiO is smart many are event-triggered, only the current IO event occurs to notify the user thread to perform IO operations, the current operation will not block after the end of the wait can perform other business operations to wait for the next event, like the bank to withdraw money, a way to queue silly wait until you, one is registered automatic arranging, after registration, why do you go to do? When it's your turn, the clerk will call you to do the work, the normal mind would like the way back. Compared to the OIO thread and the n pair N,nio of the connection, only a few threads handle n connections, which is known as the multiplexed model, which is not standard multiplexing for Netty, Netty IO events and non-IO events are dispatched by the same thread pool. A parameter to control the execution time of IO and non-IO events is more complex in this way, but CPU usage is higher because there is very little context switch.

But there is no free lunch, and NIO brings performance advantages, but the complexity of using it has soared compared to OIO. For example, I want to do a write operation, Oio a few lines of code is done:

OutputStream OS = S.getoutputstream (); String str = "Test"; Os.write (Str.getbytes ());
With NIO, you need a piece of code:

while (running) {Socketchannel Socketchanel = serversocketchanel.accept (); socketchanel.configureblocking (false); Socketchanel.register (Selector, selectionkey.op_read| selectionkey.op_write); int count = Selector.select (); if (Count > 0) {set<selectionkey> keys = Selector.selectedkeys ();iterator<selectionkey> iter = Keys.iterator (); while (Iter.hasnext ()) {SelectionKey key = Iter.next (), if (key.iswritable ()) {Bytebuffer buff = bytebuffer.allocate (1024x768); Buff.put ("

This can also be understood, or take the money in front of the example, the second way, the user is cool, but the bank needs to engage in a set of automatic arranging system, but also more responsible for the patience of the salesman, in short, the bank is very troublesome. In addition, NIO also brings more reliability problems. The Netty of cattle is the complexity of shielding NIO programming, simplifying the programming model, allowing developers to focus on business logic, and addressing some of the reliability issues in NIO. The following is a study of several reliability problem processing for Netty.

Connection Timeout processing

In Oio, the connection time-out is very simple, just call a Setconnecttimeout method to set the connection time-out, but the JDK's NIO API does not provide a way to set the time-out, obviously regardless of the server resource or user experience angle, The connection must use the timeout time, on the one hand the server handle resource is limited, since I can not serve you so please let go soon, long time unable to connect to the server is very necessary to release the handle resources, on the other hand when the user initiates the operation if the system does not give the response for a long time is obviously not a good experience, It is also very necessary to prompt the user to be unable to connect to the server at this time after the timeout. Netty provides an API to set the connection time-out period, and the time-out by Channleoption.connect_timeout_millis setting the Timetou,netty process is to start a delay task immediately after the call is built. The task executes after the timeout time, the task performs a close operation, the connection is established successfully, the task is canceled, and the code is processed in the Abstractniounsafe class's Connect method:

@Overridepublic void Connect (final socketaddress remoteaddress, final socketaddress localaddress, final Channelpro    Mise promise) {if (!promise.setuncancellable () | |!ensureopen (PROMISE)) {return; } try {if (connectpromise! = null) {throw new IllegalStateException ("connection attempt already mad        E ");        } Boolean wasactive = IsActive ();        if (Doconnect (remoteaddress, localaddress)) {Fulfillconnectpromise (Promise, wasactive);            } else {connectpromise = promise;            requestedremoteaddress = remoteaddress;            Schedule Connect Timeout.            int connecttimeoutmillis = config (). Getconnecttimeoutmillis ();                    if (Connecttimeoutmillis > 0) {connecttimeoutfuture = EventLoop (). Schedule (new Onetimetask () { @Override public void Run () {channelpromise connectpromise = Abstrac TNioChannel.this.connectProMise Connecttimeoutexception cause = new Connecttimeoutexception ("Connection timed out:" + Remo                        teaddress);                         if (connectpromise! = null && connectpromise.tryfailure (cause)) {Close (voidpromise ());            }}}, Connecttimeoutmillis, timeunit.milliseconds); } promise.addlistener (New Channelfuturelistener () {@Override public void Operat                        Ioncomplete (channelfuture future) throws Exception {if (future.iscancelled ()) {                        if (connecttimeoutfuture! = null) {Connecttimeoutfuture.cancel (false);                        } connectpromise = null;                    Close (Voidpromise ());        }                }            }); }} catch (Throwable t) {if (T InstanceoF connectexception) {Throwable NewT = new Connectexception (t.getmessage () + ":" + remoteaddress);            Newt.setstacktrace (T.getstacktrace ());        t = NewT;        } promise.tryfailure (t);    Closeifclosed (); }}

Sub-Package transfer

In the TCP protocol, the packet transmission is very, a piece of information may reach the destination several times, in Oio this is not a problem, because Oio is a silly equation, not read the complete information it will not stop, but NiO is different, it is based on the event, only the data came it will read, then the problem comes, What to do when the data is parsed for business after reading the data? For example, I want to parse a number of shapes, but currently only read two bytes of data, and two bytes of data in the subsequent transmission packet, due to the non-blocking of NIO, business data parsing time becomes a big problem, because it may not be able to fetch full data at once.

Based on the above problem, the Netty framework designed a replayingdecoder to solve the problem in this scenario, and the core principle of replayingdecoder is that when Replayingdecoder is doing data parsing, If you find that all the readable data in the current bytebuf is incomplete, such as I want to parse an integer, but the data in Bytebuf is less than 4 bytes, then a signal type error is thrown. The error-throwing operation is performed in Replayingdecoderbuffer, a bytebuf decorator. In the Replayingdecoder will catch an error, after snapping to the signal will be bytebuf in the reading pointer to the previous breakpoint (checkpoint, the default is bytebuf actually read position), and then end this parsing operation, Wait for the next IO read event. If it's just a simple number resolution problem, but if the data parsing logic is complex, there is a problem with this processing method, when the network condition is bad, the parsing logic executes repeatedly, if the parsing process is a CPU-consuming operation, then this is a big burden on the CPU. This problem can be solved by breakpoints and state machine in Replayingdecoder, the user can save the previous parsing result, state and read pointer breakpoint in Replayingdecoder, for example, I want to parse 8 bytes of data, parse the front and back four bytes into the number of shaping, and add the two data as the result of the analysis, the code is as follows:

public class Towintegerreplayingdecoder extends replayingdecoder<integer> {private static final int parse_1 = 1;pri vate static final int parse_2 = 2;private int number1;private int number2; @Overrideprotected void Decode (Channelhandlercon Text CTX, Bytebuf in,list<object> out) throws Exception {switch (State ()) {Case parse_1:number1 = In.readint (); check Point (parse_2), break;case parse_2:number2 = In.readint (); checkpoint (parse_1); Out.add (Number1 + number2); break; Default:break;}}}
In the code, the resolution is divided into two stages, when a phase resolution is completed, the first phase of the parsing results, and update the parsing state and read pointers, so that if the data is incomplete due to the second phase of the resolution can not be completed, the next IO event triggered, the parser will go directly into the second phase of the resolution, Instead of repeating the first phase of parsing, this reduces the rate of repetition resolution. Based on this design, the Replayingdecoder must be unique to the channel, its instances cannot be shared, no channel instances must have a separate Replayingdecoder parser instance, and sharable annotations cannot be added. Because it is used in a state, if it is shared in multiple channel, then the state is out of shape.


Netty Reliability Design One

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.