Rpc-the implementation principle of synchronous API under non-blocking communication, taking Dubbo as an example

Source: Internet
Author: User

Netty in the Java nio field is basically the leader, involving high-performance network communications, the basic will be netty as the underlying communication framework, Dubbo is no exception. The following will take the Dubbo implementation as an example of how it realizes synchronous communication on the basis of NIO non-blocking communication.

Dubbo is an RPC communication framework that provides inter-process communication and provides three API invocation modes when using the Dubbo protocol +netty as the transport layer:

    1. Synchronization interface
    2. Asynchronous with callback interface
    3. Async without Callback interface

Synchronization interface for most of the environment, the communication method is simple, reliable, the client initiates the call, waits for the service side processing, the call result synchronously returns. In this way, in the high throughput, high performance (fast response time) of the service interface scenario, the most suitable, can reduce the additional consumption of asynchronous, but also facilitate the client to do consistency assurance.

Asynchronous with callback interface, with long task processing time, the client application thread does not want to block the wait, but to improve its processing ability to expect the service side processing can be asynchronous to notify the application thread. This approach can greatly increase the throughput of the client and avoid the server-side time-consuming problem of dragging the client.

Asynchronous without callback interface, some scenarios in order to further enhance the client's throughput capability, only need to initiate a server-side call, do not need to call the results of the relationship, you can use this method of communication. This can be minimized by minimizing the performance loss caused by remote calls without the need to strictly guarantee data consistency or other compensation measures.

Take a look at how Dubbo implements these three APIs. The core code in Com.alibaba.dubbo.rpc.protocol.dubbo.DubboInvoker, such as the corresponding location, belongs to the implementation part of the protocol layer. To make it easy for you to pinpoint where your code is, use it instead of just pasting it directly into your code.

Described above is three kinds of API mode, Dubbo inside through the parameters IsOneway, IsAsync to control, isoneway=true means asynchronous without callback, isasync=true means asynchronous with callback, otherwise is synchronous API. Specifically how to control, see the following code:

Isoneway==true, the client initiates a request, sets a responsefuture when the client send the request, and then directly return an empty result of the rpcresult;isasync==true. Return directly to an empty result of the Rpcresult, next when the server processing is completed, the client Netty layer receives a response through the future notification application thread, and finally in the case of synchronization, the client initiates the request, and through the Get () method to block the response to wait for the server side results.

In the case of asynchronous APIs, the combination of the NIO model is a good understanding of how it is implemented (of course, the reactor model of NIO needs to be understood first), followed by a key understanding of how the get () blocking method achieves the synchronous blocking effect based on non-blocking nio.

Go directly inside the Get () method.

You can see that it is implemented using Java's lock mechanism, which loops to determine if a response is received, or if a wait timeout is returned. The instance object for done is as follows:

Final Lock                            new Reentrantlock ();  Final Condition Done                       = Lock.newcondition (); 

Using a reentrant lock reentrantlock, gets a condition object on which to do an await operation. There is an await operation, when it is awakened, there are two conditions, the first is to wait for timeout, the default Dubbo is 1s, the second is to be awakened by other threads, that is, the response received by the server.

As soon as the signal signal is emitted, the await operation in the loop detection above returns immediately, and the next time the Isdone judgment becomes true, it jumps directly out of the loop.

A closer look at the code will reveal that one of the areas where it wakes up is a thread that has a timeout polling inside the defaultfuture, which mainly handles actions such as triggering resource recycling after a response time-out, logging exception logs, and so on.

Private Static classRemotinginvocationtimeoutscanImplementsRunnable { Public voidrun () { while(true) {                Try {                     for(Defaultfuture future:FUTURES.values ()) {if(Future = =NULL||Future.isdone ()) {                            Continue; }                        if(System.currenttimemillis ()-Future.getstarttimestamp () >future.gettimeout ()) {                            //Create exception response.Response Timeoutresponse =NewResponse (Future.getid ()); //set timeout status.Timeoutresponse.setstatus (Future.issent ()?Response.SERVER_TIMEOUT:Response.CLIENT_TIMEOUT); Timeoutresponse.seterrormessage (Future.gettimeoutmessage (true)); //handle Response.defaultfuture.received (Future.getchannel (), timeoutresponse); }} thread.sleep (30); } Catch(Throwable e) {logger.error ("Exception when scan the timeout invocation of remoting.", E); }            }        }    }    Static{Thread th=NewThread (NewRemotinginvocationtimeoutscan (), "Dubboresponsetimeoutscantimer"); Th.setdaemon (true);    Th.start (); }

It may be doubtful that this trigger action will not directly invoke Defaultfuture.received (channel channel, Response Response) to clean up the timeout directly inside the Get () method, but rather open a background thread.

Starting a time-out thread individually has two benefits:

    1. Improve time-out accuracy

The poll inside the Get () method has a timeout, and each time-out wakes up at least the timeout interval, and the worst case may wait for 2*timeout to make a timeout response. In the time-out polling thread, every 30ms traversal is detected, which can greatly increase the time-out accuracy.

2. Improve performance and reduce response time

Stripping the timeout processing logic to a single thread can reduce the time spent on the business thread, and the post-timeout processing has no direct effect on the application and can be handled asynchronously in the background. In addition, in a single thread, there is actually a performance of batch processing.

Above is the realization principle that realizes three kinds of API call on the basis of NIO communication, perhaps has more than Dubbo of processing way, can come out to discuss.

Rpc-the implementation principle of synchronous API under non-blocking communication, taking Dubbo as an example

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.