Message-based communication between systems for Distributed Java applications (2)

Source: Internet
Author: User
Tags time in milliseconds

Message-based communication between systems for Distributed Java applications (2)
Message-based Inter-System Communication Based on Java Technology

The following methods can be used to implement inter-System Communication Based on Java package: TCP/IP + BIO, TCP/IP + NIO, UDP/IP + BIO, and UDP/IP + NIO. The following describes how to implement inter-system communication between the four methods.

TCP/IP + BIO

In JavaSocket, ServerSocketTo implement inter-system communication between TCP/IP and BIO.
Socket is mainly used for establishing connections and network I/O operations. ServerSocket is mainly used for listening to server ports and obtaining Socket objects.
1. The key code for implementing the client based on Socket is as follows:

// Create a connection. If the domain name cannot be resolved, an UnknownHostException will be thrown. If the connection fails, an IOException will be thrown. To control the connection establishment timeout, you can call new Socket () first (), then call socket. connect (SocketAddress type Destination Address, timeout in milliseconds) Socket socket = new Socket (target IP address or domain name, target port ); // create a BufferedReaderBufferedReader in = new BufferedReader (new InputStreamReader (socket. getInputStream (); // creates a PrintWriterPrintWriter out = new PrintWriter (socket. getOutputStream (), true); // send string information to the server. Note that no exception information is thrown even if the write fails, and it will be blocked until the write operation system or network IO exception occurs. println ("hello"); // blocking reads the server's return information. The following code blocks the server's return information or network IO exception, if you want to stop blocking after a period of time, you need to call the Socket after creating the socket object. setSoTimeout (timeout in milliseconds) in. readLine ();

2. The key code on the server side is as follows:

// Create a listener for the specified local port. If a port conflict occurs, SocketException is thrown. If other network I/O exceptions occur, IOExceptionServerSocket ss = new ServerSocket (listener port) is thrown) // accept the client connection request and return the Socket object to interact with the client. The interaction method is the same as that of the client. getInputStream and Socket. getOutputStream is used to perform read/write operations. This method is always blocked until a client sends a connection creation request. If you want this method to block up to a certain amount of time, after creating a ServerSocket, call its setSoTimeout (timeout in milliseconds) Socket socket = ss. accept ();

3. Performance analysis of this mode
The above is a simple example of inter-System Communication Based on Socket and ServerSocket. In actual systems, the client usually needs to send multiple requests to the server at the same time, while the server must accept the requests sent by multiple connections at the same time, the above code is obviously not satisfactory.
To enable the client to send multiple requests to the server at the same time, the simplest method is to generate multiple sockets.

However, there are two problems:

A) Too many sockets will consume too much local resources. When there are many client machines and few server machines, too many clients are generated, and the server needs to support a very high number of connections. B) it is usually slow to generate a Socket (establish a connection). Therefore, frequent creation may result in insufficient system performance.

4. Connection Pool
In view of these two problemsConnection PoolIt is better to maintain the Socket. On the one hand, it limits the number of sockets that can be created; on the other hand, it puts the Socket into the pool to avoid performance degradation caused by repeated Socket creation. The database connection pool is a typical example of this method.

5. Connection Pool issues
However, the connection pool may cause another problem. The number of sockets in the connection pool is limited, but there may be many requests to use Socket at the same time. In this case, fierce competition and waiting will occur; another issue to be aware of is reasonable control.Response timeoutIf no timeout is set, the client-related requests are waiting infinitely when the server-side processing slows down, and the client resources are limited.

Therefore, in this case, it is easy to cause the client to fail when a problem occurs on the server side. The specific timeout value depends on the number of requests that the client can handle and the processing time of the server. To ensure both performance and error rate, you can use the TCP/IP + BIO method.Socket.setSoTimeoutTo set the timeout time for the response.

To ensure that the server can accept requests sent by multiple connections at the same time, the common method is to put the Socket into a thread for processing after the accept obtains the Socket, this method is usually called a connection and a thread. In this way, the server can accept multiple connections to send requests. The disadvantage of this method is that a thread is required no matter whether there are real requests on the connection. To avoid excessive thread creation, the number of threads to be created must be limited because BIO can support a limited number of connections.

TCP/IP + NIO

In Java, You can implement inter-system communication through TCP/IP + nio Based on the Channel and Selector classes in java. NIO. channels. There are two types of channels: SocketChannel and ServerSocketChannel.
SocketChannel is used to establish connections, listen for events, and read/write operations. ServerSocketChannel is used to listen on ports and Connection events;
The program uses Selector to obtain whether there are any events to be processed.

1. The key code for implementing the client based on these two classes is as follows:

SocketChannel channel = SocketChannel. open (); // set to non-blocking channel. configureBlocking (false); // for non-blocking mode, false is returned immediately, indicating that the connection is creating a channel. connect (SocketAddress); Selector selector = Selector. open (); // register selector with the channel and the connection event channel you are interested in. register (selector, SelectionKey. OP_CONNECT); // block an IO event of interest or timeout. If you want to wait until an IO event of interest occurs, you can call the select method without parameters, if you want to directly return an event of interest without blocking, you can call the selectNow method int nKeys = selector. select (time-out time in milliseconds) // if nKeys is greater than zero, it indicates that an IO event of interest occurs SelectionKey sKey = null; if (nKeys> 0) {Set
  
   
Keys = selector. selectedKeys (); for (SelectionKey key: keys) {// if (key. isConnectable () {SocketChannel SC = (SocketChannel) key. channel (); SC. configureBlocking (false); // registers IO read events of interest. Generally, write events are not directly registered. The write events are always writable when the sending buffer is not full, therefore, if you register a write event without writing data, it is easy to cause 100% CPU consumption. sKey = SC. register (selector, SelectionKey. OP_READ); // establishes the connection SC. finishConnect ();} // a stream can read else if (key. isReadable () {ByteBuffer buffer = ByteBuf Fer. allocate (1024); SocketChannel SC = (SocketChannel) key. channel (); int readBytes = 0; try {int ret = 0; try {// read the currently readable stream, SC. read returns the number of bytes successfully copied to bytebuffer. This step is a blocking operation and the value may be 0. When the stream ends,-1 while (ret = SC. read (buffer)> 0) {readBytes + = ret ;}} finally {buffer. flip () ;}} finally {if (buffer! = Null) {buffer. clear () ;}}// the else if (key. isWritable () {// cancel the key registration for the OP_WRITE event. interestOps (key. interestOps ()&(~ SelectionKey. OP_WRITE); SocketChannel SC = (SocketChannel) key. channel (); // this step is a blocking operation until an exception occurs in the sending buffer or network I/O of the operating system. The number of bytes written successfully is returned. When the sending buffer of the operating system is full, 0 int writtenedSize = SC is returned here. write (ByteBuffer); // if not written, continue to register the OP_WRITE event if (writtenedSize = 0) {key. interestOps (key. interestOps () | SelectionKey. OP_WRITE) ;}} selector. selectedKeys (). clear ();} // you can directly call the channel for the stream to be written. write. You must register the OP_WRITE event int wSize = channel. write (ByteBuffer); if (wSize = 0) {key. interestOps (key. interestOps () | SelectionKey. OP_WRITE );}
  

As shown in the preceding figure, NIO is a typical Reactor mode. It registers events of interest and scans for events of interest to perform relevant actions.

2. The key code on the server side is as follows:

ServerSocketChannel ssc = ServerSocketChannel. open (); ServerSocket serverSocket = ssc. socket (); // bind the port serverSocket to be listened on. bind (new InetSocketAddress (port); ssc. configureBlocking (false); // register the connection creation event ssc that you are interested in. register (selector, SelectionKey. OP_ACCEPT );

Then, you can round robin selector. select in the same way as the client. The Code is as follows:

if(key.isAcceptable()){  ServerSocketChannel server=(ServerSocketChannel)key.channel();  SocketChannel sc=server.accept();  if(sc==null){      continue;}  sc.configureBlocking(false);  sc.register(selector,SelectionKey.OP_READ);}

The above is just a simple example based on TCP/IP + NIO, let's also take a look at how TCP/IP + NIO-based clients can send multiple requests at the same time and the server can accept the requests sent by multiple connections.

3. Performance analysis of this mode
There is no difference between TCP/IP + NIO and TCP/IP + BIO for sending multiple requests from the client. However, NIO can achieveNot blockedTherefore, if the response returned by the server can carry the request identifier, the client can useConnection multiplexingThat is, after each SocketChannel sends a message, it can continue sending other messages without waiting for a response. This method can reduce the resource competition caused by the connection pool and improve system performance;

If the connection is not reused, it can be based on Socket. the setSoTimeout method is used to control the synchronization request timeout. For connection multiplexing, the synchronization request timeout can be implemented based on BlockingQueue, the wait/notify mechanism of the object, or the Future mechanism.

GenerallyOne thread listens to Connection events, and the other or more threads Listen to network stream read/write events..

When an actual network stream read/write event occurs, it is placed in the thread pool for processing. This method is better than TCP/IP + BIO because it can accept many connections, and these connections will only be processed by creating threads when there are real requests.One request and one thread. When the number of connections is small, or the number of connections is large, and connection requests are sent frequently, the TCP/IP + NIO method will not bring too many advantages, but in actual scenarios, generally, the server must support a large number of connections, but these connections do not send many requests at the same time.

When developing Java NIO programs based on Sun JDK, pay special attention to the handling of the IOException thrown by selector. select and the direct return of selector. select without blocking. Both of these conditions may cause CPU consumption to reach 100%, for selector. when select throws an IOException, you can use the Bypass Method to capture the exception and sleep the current Thread for a period of time or recreate the Selector. To avoid direct return without blocking selector. select, you can use the modification suggestions mentioned in the bug library.

As can be seen from the above, for high-traffic systems, the TCP/IP + NIO method combined with certain transformation can bring higher performance on the client side, and support higher connections on the server side.

UDP/IP + BIO

Java also uses the Socket mechanism for UDP/IP network data transmission, but the Socket under UDP/IP does not need to establish a connection, because UDP/IP is not connected, therefore, two-way communication is not possible. This requires that if two-way communication is required, both ends must become UDP servers.
In JavaDatagramSocket and DatagramPacketTo implement inter-system communication in the UDP/IP + BIO mode,Mongoramsocket monitors ports and reads and writes data. DatagramPacket is transmitted as a data stream object..

1. The key code for implementing the client based on these two classes is as follows:

// Because the UDP/IP address is not connected, If you want two-way communication, you must start a listening port to assume the responsibilities of the server. If you cannot bind the port to the specified port, socketexceptionexcepramsocket serverSocket = new DatagramSocket (listener port); byte [] buffer = new byte [65507]; DatagramPacket datagepacket = new DatagramPacket (buffer, buffer. length); DatagramSocket socket = new DatagramSocket (); DatagramPacket packet = new DatagramPacket (datas, datas. length, server, port); // block packet sending to the specified server and port. If a network IO exception occurs, an IOException is thrown. If the target address and port cannot be connected, PortUnreachableExceptionsocket is thrown. send (packet) // block and synchronously read the stream information. If the received stream information is longer than the packet length, the longer information will be deleted. You can call mongoramsocket. setSoTimeout (timeout in milliseconds) is used to set the timeout time for reading streams serverSocket. receive (paiepacket)

The structure of the server-side code is basically the same as that of the client-side code, which is not listed here.

Because no connection is established between the two ends of UDP/IP communication, there will be no competition for TCP/IP communication connections,Only the final read/write flow is synchronized..
Generally, the server needs to receive multiple requests at the same time by putting each packet into a thread for processing.

UDP/IP + NIO

In Java, mongoramchannel and ByteBuffer can be used to implement inter-system communication through UDP/IP + NIO,Mongoramchannel is responsible for listening to ports and reading and writing, and ByteBuffer is used for data stream transmission..

1. The key code for implementing the client based on these two classes is as follows:

DatagramChannel receiveChannel = DatagramChannel. open (); receiveChannel. configureBlocking (false); DatagramSocket socket = receiveChannel. socket (); socket. bind (new InetSocketAddress (rport); Selector selector = Selector. open (); receiveChannel. register (selector, SelectionKey. OP_READ); then you can read the stream information in the same way as the selector traversal in TCP/IP + NIO. Specified ramchannel sendChannel = Specified ramchannel. open (); sendChannel. configureBlocking (false); SocketAddress target = new InetSocketAddress ("127.0.0.1", sport); sendChannel. connect (target); // blocking the write stream. If the sending buffer is full, 0 is returned. You can register SelectionKey. the OP_WRITE event allows you to perform write operations when writing data. The method is basically the same as that of TCP/IP + NIO sendChannel. write (ByteBuffer );

The server code is basically the same as the client code, so it is not described one by one.

From the code above, for UDP/IP, NIO only performs IO operations when the stream is to be read or writable, instead of directly blocking the current thread like BIO.

Multicast protocol for communication

The above lists the one-to-one (one-to-one "communication" between the client and the server) communication methods based on Java packages. In actual scenarios, generally, messages are sent to multiple machines. You can set up a connection for each target machine. This method puts a lot of network traffic pressure on the message sending end. For example, when a message is transmitted in a video data scenario, there is also a network protocol extended based on UDP/IPMulticast Protocol,The multicast protocol is used to transmit a copy of data over the network, instead of transmitting a copy of data to each receiver by the sender.In this way, the network traffic is greatly reduced.

In Java, You can implement multicast network communication based on MulticastSocket and DatagramPacket. MulticastSocket is a class derived from DatagramSocket. Its role is to implement network communication based on UDP/IP. In multicast communication, the difference is that the receiving data end receives data by adding it to multicast groups. Similarly, the sending data must be added to multicast groups for sending, the target address of multicast has a specified address range.224.0.0.0 and 239.255.255.255.

1. The key code of the server that implements network communication based on multicast is as follows:

// Multicast address InetAddress groupAddress = InetAddress. getByName ("224.1.1.1"); MulticastSocket server = new MulticastSocket (port); // Add to multicast. if the address is not a multicast address, an IOException is thrown, when you do not want to send data to the multicast address or read data again, you can call server. leaveGroup (multicast address) server. joinGroup (groupAddress); MulticastSocket client = new MulticastSocket (); client. joinGroup (groupAddress );

Then, you can perform read and write operations in the same way as UDP/IP + BIO through the receive and send methods. The Client-side code is basically the same as the server-side code and will not be listed.

In Java applications, multicast is usually used to synchronize the statuses of multiple machines. For example, JGroups is based on the UDP/IP multicast protocol by default. Because the UDP/IP protocol is not reliable enough for data transmission, systems with high reliability requirements will want to adopt the multicast mode, at the same time, it must be reliable. For such requirements, the industry has put forward some ways to ensure Reliable implementation of Multicast: SRM (Scalable Reliable Multicast), URGCP (Uniform Reliable Group Communication Protocol ), SRM adds a validation mechanism based on UDP/IP multicast to ensure reliability. eBay uses the SRM framework to synchronize data from the primary database to various search node machines.

From the above introduction, it is difficult to use Java packages to implement message-based Inter-system communication. In order to enable developers to focus more on data processing without paying too much attention to pure technical details, the open source industry has created many excellent inter-system communication frameworks based on the above protocols. Mina is the best among them.

Related Article

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.