Architecture Design: Inter-system Communication (5)--io communication model and Java practice in the next chapter

Source: Internet
Author: User
Tags closing tag epoll throwable

Next: "Architecture design: Inter-system Communication (4)--io communication model and Java Practice Medium", we continue to explain asynchronous IO

7. Asynchronous IO

In the previous two articles, we explained the three IO models for blocking synchronous IO, non-blocking synchronous io, multiplexed io, and Java support for these three IO models. The main point is that the IO model is supported by the operating system, and these three IO models are synchronous IO, all using the " application does not ask me, I will never notice " way.

Asynchronous IO is a "subscription-notification" mode: the application registers IO snooping with the operating system and then continues to do its own thing. When an IO event occurs on the operating system and the data is ready, the appropriate function is triggered when the application is actively notified:

    • As with synchronous IO, asynchronous IO is supported by the operating system. Microsoft's Windows system provides an asynchronous IO technology:IOCP(I/O completion port,i/o completion port);

    • Because there is no such asynchronous IO technology under Linux, the asynchronous IO is simulated using epoll (the implementation of a multiplexed IO technology described above).

8, Java Support (Java AIO) 8-1, Java AIO Framework Analysis

    • The same is true of the architecture design: inter-system Communication (4)--io communication model and Java practice Medium The Java NIO Framework implementation analysis, here also does not have the Java AIO Framework all the implementation class painting, but through this structure analysis to tell you readers Java Dependency of class design and operating system in AIO

    • In this article we have repeatedly explained that the Java AIO Framework uses Windows IOCP technology under Windows and simulates asynchronous IO using Epoll multiplexing IO technology under Linux, as can be seen from some class designs of the Java AIO Framework. For example, in the framework, the specific class that is responsible for implementing the socket channel under Windows is "Sun.nio.ch.WindowsAsynchronousSocketChannelImpl", and its referenced IOCP type document annotation is:

/**
* Windows implementation of Asynchronouschannelgroup encapsulating an I/O
* Completion port.
*/

If you're interested, of course you can look at the full code (recommended from the "Java.nio.channels.spi.AsynchronousChannelProvider" category).

    • In particular, note the "Java.nio.channels.NetworkChannel" interface in the diagram, which is also implemented by the Java NIO Framework, as shown in:
8-2. code example

Below, we explain the specific use of the Java AIO Framework through a code sample, first in code, and in the main points of code writing and running:

 PackageTestasocket;ImportJava.io.IOException;ImportJava.io.UnsupportedEncodingException;Importjava.net.InetSocketAddress;ImportJava.nio.ByteBuffer;ImportJava.nio.channels.AsynchronousChannelGroup;ImportJava.nio.channels.AsynchronousServerSocketChannel;ImportJava.nio.channels.AsynchronousSocketChannel;ImportJava.nio.channels.CompletionHandler;ImportJava.util.concurrent.ExecutorService;ImportJava.util.concurrent.Executors;ImportOrg.apache.commons.logging.Log;ImportOrg.apache.commons.logging.LogFactory;ImportOrg.apache.log4j.BasicConfigurator;/** * JAVA AIO Framework test. Please make sure that * architecture design: Inter-system Communication (4)--io communication model and Java practice Medium look at this test code. * This is useful for you to understand the key points of the code. * @author Yinwenjie * * Public  class socketserver {    Static{basicconfigurator.configure (); }Private Static FinalObject waitobject =NewObject ();/** * @param args * @throws Exception */     Public Static void Main(string[] args)throwsException {/* * For thread pooling technology, I must say a few more words * 1, executors is the thread pool generation tool, we can easily generate "fixed-size thread pool", "Schedule Pool", "number of scalable threads pool".         See API Doc * 2 for details, but you can also generate pools directly from Threadpoolexecutor. * 3, this thread pool is used to get the operating system "IO event notification", not for "get IO data after the business processing."         To do the latter, you can use a pool (preferably not mixed) * 4, you can also do not use the thread pool (not recommended), if you decide not to use the thread pool, directly asynchronousserversocketchannel.open () on the line. * */Executorservice ThreadPool = Executors.newfixedthreadpool ( -); Asynchronouschannelgroup Group = Asynchronouschannelgroup.withthreadpool (ThreadPool);FinalAsynchronousserversocketchannel ServerSocket = Asynchronousserversocketchannel.open (group);//Set the port to listen "0.0.0.0" for all IP devices on this machineServersocket.bind (NewInetsocketaddress ("0.0.0.0", the));//For Asynchronousserversocketchannel Register monitoring, note only for Asynchronousserversocketchannel channel registration monitoring        //Does not include monitoring that is registered for subsequent client and server Socketchannel channelsServersocket.accept (NULL,NewServersocketchannelhandle (ServerSocket));//wait to observe the phenomenon (this has nothing to do with the principle itself, just to ensure that the daemon does not exit)        synchronized(waitobject)        {waitobject.wait (); }    }}/** * This processor class is specifically designed to respond to Serversocketchannel events. * Remember what we mentioned in "Architecture design: Communication between systems (4)--io communication model and Java practice Medium"? Serversocketchannel There is only one event: Accept client connections * @author Yinwenjie */Class Serversocketchannelhandle implements Completionhandler<asynchronoussocketchannel, void> {/** * Log * *    Private Static FinalLog LOGGER = Logfactory.getlog (Serversocketchannelhandle.class);PrivateAsynchronousserversocketchannel Serversocketchannel;/** * @param serversocketchannel * *     Public Serversocketchannelhandle(Asynchronousserversocketchannel Serversocketchannel) { This. Serversocketchannel = Serversocketchannel; }/** * Note that we observe the IDs of this, Socketchannel, attachment three objects separately. * To observe the changes of these three objects when different client connections arrive, to illustrate the Serversocketchannelhandle listening mode */    @Override     Public void completed(Asynchronoussocketchannel Socketchannel, Void attachment) {ServerSocketChannelHandle.LOGGER.info ("Completed (asynchronoussocketchannel result, bytebuffer attachment)");//Always re-register for monitoring (one registration, one response), but since the "file status identifier" is exclusive, there is no need to worry about "missing" events         This. serversocketchannel.accept (Attachment, This);//Register the "read" event for this new Socketchannel so that the operating system proactively notifies the application when the data is received and ready        //Here, since we are going to add together the data that the client has transmitted over and over again, we attach a StringBuffer object as an "attachment" to this channel.        //Bytebuffer Readbuffer = Bytebuffer.allocate ( -); Socketchannel.read (Readbuffer,NewStringBuffer (),NewSocketchannelreadhandle (Socketchannel, Readbuffer)); }/* (non-javadoc) * @see java.nio.channels.completionhandler#failed (java.lang.Throwable, Java.lang.Object) */
         @Override     Public void failed(Throwable exc, Void attachment) {ServerSocketChannelHandle.LOGGER.info ("failed (Throwable exc, bytebuffer attachment)"); }}/** * is responsible for monitoring each Socketchannel data acquisition event. <p> * IMPORTANT NOTE: A socketchannel will have an independent working Socketchannelreadhandle object (Implementation of the Completionhandler interface), which will also have a "File status indicator" Object FileDescriptor, * An independent programmer-defined buffer cache (here we use bytebuffer), * So don't worry about the "channeling" scenario on the server side, because the Java AIO Framework has helped you organize it. <p> * But most importantly, the object used to generate the channel: Asynchronouschannelprovider is a singleton pattern, regardless of which group of Socketchannel, * is an object reference (but that's okay, Because you do not directly manipulate this Asynchronouschannelprovider object). * @author Yinwenjie * *Class Socketchannelreadhandle implements Completionhandler<integer, stringbuffer> {/** * Log * *    Private Static FinalLog LOGGER = Logfactory.getlog (Socketchannelreadhandle.class);PrivateAsynchronoussocketchannel Socketchannel;/** * Specifically for this channel data cache operation Bytebuffer<br> * Of course, you can also be passed in as a attachment form of completionhandler.     <br> * This is, in this example code, attachment is used by us to record all the transmitted StringBuffer. */    PrivateBytebuffer Bytebuffer; Public Socketchannelreadhandle(Asynchronoussocketchannel Socketchannel, Bytebuffer bytebuffer) { This. Socketchannel = Socketchannel; This. Bytebuffer = Bytebuffer; }/* (non-javadoc) * @see java.nio.channels.completionhandler#completed (java.lang.Object, Java.lang.Object) */
         @Override     Public void completed(Integer result, StringBuffer historycontext) {//If the condition is true, the client terminates the TCP socket actively, then the service end is ready.        if(Result = =-1) {Try{ This. Socketchannel.close (); }Catch(IOException e)            {SocketChannelReadHandle.LOGGER.error (e); }return; } SocketChannelReadHandle.LOGGER.info ("Completed (Integer result, Void attachment): Then we'll take out the prepared value in the channel.");/ * In fact, since we know from integer result that this channel gets the total length of data from the operating system * So in fact, we do not need to switch to "read mode", but in order to ensure that the code is normative, it is recommended that switching. * In addition, both the Java AIO Framework and the Java NIO Framework will appear with the "total buffer capacity" less than "the total amount of data currently obtained from the operating system", * but the difference is that in the Java AIO Framework, we don't need to specifically consider Because the Java AIO Framework has done the processing for us (multiple notifications) * */         This. Bytebuffer.flip ();byte[] contexts =New byte[1024x768]; This. Bytebuffer.get (Contexts,0, result); This. Bytebuffer.clear ();Try{String nowcontent =NewString (Contexts,0, result,"UTF-8");            Historycontext.append (nowcontent); SocketChannelReadHandle.LOGGER.info ("================ Current transmission results:"+ Historycontext); }Catch(Unsupportedencodingexception e)        {SocketChannelReadHandle.LOGGER.error (e); }//If the condition is true, the description has not received the "closing tag"        if(Historycontext.indexof ("Over") == -1) {return; }//=========================================================================        //And the code of the previous article is the same, we use the "over" symbol as the client complete information token        //=========================================================================SocketChannelReadHandle.LOGGER.info ("======= received complete information to begin processing business ========="); Historycontext =NewStringBuffer ();//Continue monitoring (one-time notification)         This. Socketchannel.read ( This. Bytebuffer, Historycontext, This); }/* (non-javadoc) * @see java.nio.channels.completionhandler#failed (java.lang.Throwable, Java.lang.Object) */
         @Override     Public void failed(Throwable exc, StringBuffer historycontext) {SocketChannelReadHandle.LOGGER.info ("===== the client shuts down and the server shuts down the TCP channel");Try{ This. Socketchannel.close (); }Catch(IOException e)        {SocketChannelReadHandle.LOGGER.error (e); }    }}
8-2-1, key points to explain
    • Note In the Java NIO Framework, we are talking about an important concept, "selector" (selector). It replaces all registered channels in the application query into the operating system for IO event polling, manages the currently registered channel collection, locates the channel where the event occurred, and so on, but in the Java AIO Framework, because the application is not "polling", but the subscription-notification method, it is no longer necessary " Selector "(selector), changed from channel channels directly to the operating system registration monitoring .

    • JAVA AIO Framework, only two kinds of network IO channel "Asynchronousserversocketchannel" (server listening Channel), "Asynchronoussocketchannel" (socket socket channel) are implemented. But regardless of the channel they have a separate filedescriptor (file identifier), attachment (attachments, attachments can make arbitrary objects, like "channel context"), and are referenced by a separate Socketchannelreadhandle class instance. We use the debug operation to see their reference structure:

During the test, we started two clients (what language the client uses to write, either in a blocking or non-blocking manner, as long as the TCP socket socket is supported). If you want to see how the client is written, you can see my "Architecture Design: Inter-system Communication (3)--io communication model and Java Practice" example of the client code in this article), and then we observe the server-side processing of these two client channels:

As you can see, the two Windowsasynchronoussocketchannelimpl objects created on the server side for client 1 and client 2 are:

Client 1:windowsasynchronoussocketchannelimpl:760 | filedescriptor:762

Client 2:windowsasynchronoussocketchannelimpl:792 | filedescriptor:797

Next, we let two clients send information to the server side, and observe the server-side processing situation. The client 1 sends a message and the client 2 sends a message, as shown in the server-side processing:

Client 1:windowsasynchronoussocketchannelimpl:760 | filedescriptor:762 | socketchannelreadhandle:803 | heapbytebuffer:808

Client 2:windowsasynchronoussocketchannelimpl:792 | filedescriptor:797 | socketchannelreadhandle:828 | heapbytebuffer:833

It is apparent that the Socketchannelreadhandle (processor) objects used by the server side to process each client channel are independent and the referenced Socketchannel objects are independent .

    • Java NiO and the Java AIO Framework, in addition to removing selector because of the implementation of the operating system, other important concepts exist, such as the concept of the channel mentioned above, and the buffer cache used in the demo code. In fact, Java NIO and the Java AIO Framework can be seen as a complete set of "High concurrency IO Processing" implementations.
8-2-2, and improvements may be

Of course, the above code is the sample code, and the goal is to give you an idea of the basic use of the Java AIO Framework. So it has a lot of room for transformation, such as:

    • In a production environment, we need to record "User login information" on this channel. Then this requirement can be implemented using the "attachments" feature in Java AIO.

    • In this article and above ("Architecture design: Communication between systems (4)--io communication model and Java Practice Medium"), we use the "custom text" format to transfer content and check the "over" keyword. But in a formal production environment, will you use this?

    • Obviously not, because its compression rate is not high. Or we'll use the JSON format: because it has a better information structure at the same compression rate, we can also use Protobuffer: because it combines transfer efficiency with good information structure You can even use the TLV format: Provide good information transfer efficiency (it doesn't even have an extra byte description), and you can refer to the architecture design: inter-system Communication (1)-Overview from "chat" to the beginning of the article.

    • Remember that both the Java AIO and the Java NIO Framework are used by the thread pool (and of course you can not), the thread pool usage principle must be used only by the business processing part , and immediately end the execution of the thread (also back to the thread pool or destroy it). There is also a thread pool in the Java AIO framework that is used by the notification processor because the Java AIO Framework is based on the subscription-notification model, and the subscription operation can be done by the main thread, but you cannot always require that concurrent "notification" operations in the application be done on the main thread ^_^.

    • The best way to improve, of course, is to use Netty or Mina.

8-3, why there are Netty

Then some readers may ask, since Java Nio/java AIO has implemented the underlying support of the mainstream operating systems, then why mainstream Java NIO technology now is Netty and Mina? The answer is simple: For better use , here are some examples:

    • Although the Java NIO and Java AIO Framework provides support for multiplexing io/asynchronous IO, it does not provide a good encapsulation of the upper "information format". For example, the first two do not provide encapsulation for Protocol Buffer, JSON, these information formats, but the Netty framework provides these data format encapsulation (based on the responsibility chain mode encoding and decoding function)

    • To write a reliable, maintainable, high-performance (note their sort) Nio/aio server application. In addition to the framework itself to be compatible with the implementation of various operating systems. What's more, it should also handle many of the top-level services, such as the client's permissions, the information format encapsulation mentioned above, and the simple data read. These Netty frameworks provide support for responses.

    • The JAVA NIO framework exists with a poll/epoll bug:selector doesn ' t block on Selector.select (timeout), which does not mean that CPU usage will become 100% (this is the underlying JNI problem, The upper layer to deal with this exception is actually better done). Of course, this bug can only be reproduced on the Linux kernel.

    • This issue has not been fully resolved in JDK version 1.7: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=2147719. Although Netty 4.0 is also encapsulated based on the Java NIO Framework (described in Netty in the Nioserversocketchannel class above), Netty has already handled the bug.

    • For other reasons, after using Netty, you can compare yourself.

9, the following text trailer

Through three articles, we introduced the operating system's four IO models, and explained the Java support for these four IO models, as well as the code explanation. There is still not enough reader feedback, such as the typical Epoll technology work details are not explained, there is no performance comparison of various IO models, and so on. Don't panic, I plan for the next 3-4 months we will discuss "inter-system communication technology", so just want to do "load balancing" that series of columns, we will be in the back of the time to complete the completion. Of course, my technical level is limited, the purpose of blogging is mainly to share and summarize, so you are welcome to many readers Spit groove.

Starting with the next article, we will talk about the content of one to two articles, discussing the Netty framework (with the Netty4.0 version as the basis for discussion). We will then begin introducing the Java rim and booting from rim into the introduction of RPC technology.

Copyright NOTICE: Welcome reprint, but look at my hard work, please specify the source: Http://blog.csdn.net/yinwenjie

Architecture Design: Inter-system Communication (5)--io communication model and Java practice in the next chapter

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.