NIO framework-mina source code parsing (5): NiO super trap and communication with Mina using synchronous Io

Source: Internet
Author: User
NIO framework-mina source code analysis (1): Background


NIO framework-mina source code analysis (2): Mina Core Engine
NIO framework-mina source code analysis (III): underlying communication and responsibility chain model application


NIO framework-mina source code parsing (4): processing, encoding, and decoding of stick packets and broken packets



1. Nio super trap


The reason why NiO is a super trap is that, in the first sentence of this series, the customer's business system is paralyzed due to defects in use. Of course, I have tracked this issue, including a deep understanding of the Mina source code, but the root cause of this problem is not Mina, it is a problem at the bottom layer of JDK.


At the underlying layer of JDK, In order to wake up threads waiting on Io, two ports are used on Windows to establish connections for message sending. See the following code:


public class NIOTest {@Testpublic void test1(){    final int MAXSIZE=1000;           Selector [] sels = new Selector[ MAXSIZE];            try{                for( int i = 0 ;i< MAXSIZE ;++i ) {                    sels[i] = Selector.open();                    Thread.sleep(1000*10);                }                            }catch( Exception ex ){                ex.printStackTrace();            }}}


That is to sayEach time selector. open () is called, two random available ports are occupied., Communication --This is the root cause of the problem..

Of course, for our project, we need to solve this problem in two steps. First, it is easier to limit the number of ports to the acceptable range. We can only call selector once. the open () method can be used, and the single-profit mode is used. Step 2, because selector. the open () method uses the currently available random port of the system each time, so it may occupy the customer's service port. Therefore, we must set the selector. the port opened by open () is limited to a certain range. It is best to use the code to specify which ports to use, but we haven't found them until now. If you have any method, thank you for telling me ....,.


Selector is summarized as follows:
In Windows, selector. open () will establish two TCP links with itself. Not only two TCP connections and ports are consumed, but also file descriptors are consumed.
In Linux, selector. open () creates two pipelines on its own and on its own. It also consumes two system file descriptors.
From: http://blog.csdn.net/haoel/article/details/2224055

So now we can simply use traditional Io to communicate with the Mina server.



2. Use synchronous Io to communicate with Mina


In fact, it is very simple. The only difficulty lies in how to encode and decode the synchronization I/O to communicate with Mina. Let's look at the following code.


Server (using Mina)

/*** Initialize the settings and start the service */Public void startserver () {logger. debug ("Mina Server start"); int Port = sysevnvar. managerport; logger. debug ("Manager port:" + port); ioacceptor acceptor = new niosocketacceptor ();/** log settings */acceptor. getfilterchain (). addlast ("logger", new loggingfilter (); // The encoding and decoding factory. The technology used is the objectoutstreamobjectserializationcodecfactory objscodec = new objectserializationcodecfactory (); objscodec. setdecodermaxobjectsize (defaultdecoder); objscodec. setencodermaxobjectsize (defaultdecoder);/** data conversion, encoding setting */acceptor. getfilterchain (). addlast ("codec", new protocolcodecfilter (objscodec);/** set service processing class */acceptor. sethandler (serverhandler);/** set the buffer capacity */acceptor. getsessionconfig (). setreadbuffersize (defaultbuffersize);/** set idle time */acceptor. getsessionconfig (). setidletime (idlestatus. both_idle, defaultidletime); try {/** bind port */acceptor. BIND (New inetsocketaddress (port); logger.info ("Mina Server Bind port (" + port + ") sucess");} catch (ioexception e) {logger. error ("Mina Server Bind port (" + port + ") fail:" + E. getmessage (), e );}}

Client (using synchronous Io)


Public void sendmessagetomanager (hyrequest request) {Socket socket = NULL; bufferedinputstream inbuff = NULL; outputstream outbuff = NULL; try {INTEGER Port = integer. parseint (hyglobalconfigurecacheimpl. get ("managerport "). tostring (); string host = hyglobalconfigurecacheimpl. get ("managerip "). tostring (); socket = new socket (host, Port); inbuff = new bufferedinputstream (New datainputstream (socket. getinputs Tream (); outbuff = socket. getoutputstream (); string JSON = hyjsonutil. reqeusttojsonstr (request); // encoding starts, enabling Mina to parse iobuffer Buf = iobuffer. allocate (64); Buf. setautoexpand (true); Buf. putobject (JSON); Buf. flip (); byte [] bytes = new byte [Buf. limit ()]; Buf. get (bytes); // The encoding is complete and is directly output to the client outbuff. write (bytes); outbuff. flush (); If (request. getoperation ()! = NULL &&! "Quit ". equals (request. getoperation () {string allreadstr = new string (); byte [] B = new byte [512*1024]; int Len; byte [] TMP = new byte [0]; If (LEN = inbuff. read (B ))! =-1) {TMP = new byte [Len]; system. arraycopy (B, 0, TMP, 0, Len);} Loger. debug ("Len:" + Len); // decoding starts. byte [] is the data iobuffer in = iobuffer passed by Mina. wrap (TMP); object OBJ = NULL; try {Loger. debug ("in:" + in); OBJ = in. getObject (); // decodes and ends Loger. debug ("parse success");} catch (exception e) {// todo auto-generated catch blocke. printstacktrace (); Loger. debug ("go to exception"); Loger. warn ("Nio parse exception", e); OBJ = "exce Ption ";} allreadstr = (string) OBJ; loger.info (" Receive message from "+ socket. getremotesocketaddress (). tostring () + ", message:" + allreadstr); // The request message is converted to the hyresponse object hyresponse response = hyjsonutil. gethyresponse (allreadstr); hyrequest = new hyrequest (); hyresponsedispatcher = hyclienthandler. gethyresponsedispatcher (); hyresponsedispatcher. responseprocess (hyrequest, response); If (hyrequest. geto Peration ()! = NULL) {sendmessagetomanager2 (hyrequest) ;}} catch (exception e) {e. printstacktrace () ;}finally {try {If (null! = Outbuff) outbuff. Close ();} catch (ioexception E1) {// todo auto-generated catch blocke1.printstacktrace ();} Try {If (null! = Inbuff) inbuff. Close ();} catch (ioexception E1) {// todo auto-generated catch blocke1.printstacktrace ();} If (socket! = NULL) {try {socket. Close () ;}catch (ioexception e ){}}}}

I read the comments in the Code and how to code and decode them. In fact, I directly read the Mina source code and copied the tool class of the Mina encoding and decoding method to our client, in this way, synchronous Io and Mina can be easily used for communication.



??

NIO framework-mina source code parsing (5): NiO super trap and communication with Mina using synchronous Io

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.