Dubbo_ Remote Synchronous Invocation principle

Source: Internet
Author: User

The Dubbo default protocol uses a single long connection and NiO asynchronous communication , which is suitable for service invocation with large amount of small data volume, and the number of service consumer machines is much larger than the number of service provider machines.


Dubbo the default protocol, using mina1.1.7+hessian3.2.1-based tbremoting interactions.

    • Number of connections: Single connection
    • Connection mode: Long connection
    • Transport protocol: TCP
    • Transmission mode: NIO asynchronous transmission
    • Serialization: Hessian binary serialization
    • Scope of application: Incoming outgoing parameter packet is small (recommended less than 100K), consumers more than the number of providers, a single consumer can not be full of providers, try not to transfer large files or super-large strings with the Dubbo protocol .
    • Applicable scenario: General remote Service method invocation

Typically, a typical synchronous remote invocation should look like this:

1,The client thread calls the remote interface, sends the request to the server, and the current thread should be in a "paused" state, that is, the thread cannot be executed backwards, and must get the server's own results before it can be executed backwards.2, the service ends up with a client request, processes the request, and gives the result to the client

3, the client receives the result, and the current thread continues to execute

Dubbo uses the Socket (using the Apache Mina framework to make the underlying call) to establish long connections, send and receive data, and send messages using the iosession of the Apache Mina framework.  Dubbo The bottom layer uses the socket to send the message in the form of data transfer, combined with the Mina framework, using the iosession.write () method, after this method call for the entire remote call ( From the request to the receipt of the result is an asynchronous, that is, for the current thread, the request is sent out, the thread can be executed back, as for the server side of the result, after the server processing is completed, and then sent to the client in the form of a message. so there are 2 questions:
    • How does the current thread let it "pause" and wait until the result comes back and then executes backwards?
    • As mentioned earlier,socket communication is a full-duplex approach, if there are multiple threads making remote method calls at the same time, there will be a lot of message delivery on the socket connection between client server. The order may also be messy, after the server finishes processing the results, send theresult message to the client, theclient receives a lot of messages, how to know which message result is which thread was originally called?
The rationale is as follows:
  1. The client one thread calls the remote interface, generates a unique ID (such as a random string,uuid, etc.), andDubbo is a cumulative number using Atomiclong starting from 0.
  2. The packaged method invocation information (such as the calling interface name, method name, parameter value list, and so on), and the callback object that handles the result callback, are all encapsulated together to form an object
  3. put (ID, object) into the global concurrenthashmap that specifically holds the call information
  4. encapsulates ID and packaged method invocation information into an object connrequest, sent asynchronously using Iosession.write (connrequest)
  5. The current thread then uses the get () method of callback to try to get the result that is returned remotely, inside get (), using synchronized to get the lock of the callback object callback, and then first to detect if the result has been obtained. If not, then call callback's Wait () method to release the lock on the callback and leave the current thread in a wait state.
  6. After the server receives the request and processes it, sends the result (the result contains the preceding ID, that is, the callback) to the client, the client socket that is specifically listening for the message receives the message, parses the result, takes the ID, and then from the previous Concurrenthashmap inside Get (ID) to find callback, set the method call result to callback object.
  7. The listener thread then uses synchronized to get the lock of the callback object callback (because the previous call to wait (), that thread has freed the callback lock), and then Notifyall (), Wake up the thread that is waiting before continuing (thecallback Get () method continues execution to get the result of the call), at this point, the entire process is finished.

It is important to note that the callback object here is each call to produce a new one that cannot be shared, otherwise there will be a problem, and the ID must at least be guaranteed to be unique within a socket connection.

now, the first two questions already have an answer,

    • How does the current thread let it "pause" and wait until the result comes back and then executes backwards?
a : sir, as an object, obj, put (id,obj) in a global map, get the obj lock with synchronized, and then call Obj.wait () to let the current thread wait. Then another message listener thread waits until the server end results come up, then Map.get (ID) finds obj, then uses synchronized to obtain the obj lock, and then calls Obj.notifyall () to wake up the thread in front of the waiting state.
    • As mentioned earlier,socket communication is a full-duplex approach, if there are multiple threads making remote method calls at the same time, there will be a lot of message delivery on the socket connection between client server. The order may also be messy, after the server finishes processing the results, send theresult message to the client, theclient receives a lot of messages, how to know which message result is which thread was originally called?

a : use an ID to make it unique, then pass it to the server, and then return it back to the server, so that the result is the original thread.

Other than that:

The service side handles the message of the client and then processes it, using the line pool parallel processing without the processing of a single message

Similarly, the client receives a message from the server and uses the thread pool to process the message, and then callback

message Middleware RABBITMQ remote interface Invocation, the principle of synchronous invocation is similar to this, see:RABBITMQ Learning -9-rpcclient Send message and synchronous receive message principleKey code:
Com.taobao.remoting.impl.DefaultClient.java//synchronous invocation of the remote interface PublicObject Invokewithsync (Object apprequest, Requestcontrol control)throwsRemotingException, interruptedexception {byteprotocol =Getprotocol (Control); if(!trconstants.isvalidprotocol (protocol)) {            Throw NewRemotingException ("Invalid Serialization Protocol [" + Protocol + "] on Invokewithsync."); } responsefuture Future=invokewithfuture (apprequest, control); returnFuture.get ();//get the results when the current thread waits, Responsefuture is actually said before callback} Publicresponsefuture invokewithfuture (Object apprequest, Requestcontrol control) {byteprotocol =Getprotocol (Control); LongTimeout =gettimeout (Control); Connectionrequest Request=Newconnectionrequest (apprequest);         Request.setserializeprotocol (protocol); Callback2futureadapter Adapter=NewCallback2futureadapter (Request);         Connection.sendrequestwithcallback (Request, adapter, timeout); returnadapter;}
Callback2futureadapterImplementsresponsefuture PublicObject get ()throwsRemotingException, interruptedexception {synchronized( This) {//Rotary Lock      while(!isdone) {//is there a result?Wait ();//no result is to release the lock so that the current thread is in a wait state     } } if(ErrorCode = =trconstants.result_timeout) {     Throw NewTimeoutException ("Wait response timeout, request[" + connectionrequest.getapprequest () + "]."); } Else if(ErrorCode > 0) {     Throw Newremotingexception (errormsg);} Else {     returnAppresp;}} After the client receives the service-side result, the callback is related to the method, which is set Isdone=true and Notifyall () Public voidhandleresponse (Object _appresponse) {Appresp= _appresponse;//set the remote invocation result to callbackSetdone ();} Public voidOnremotingexception (int_errortype, String _errormsg) {ErrorCode=_errortype; ErrorMsg=_errormsg; Setdone ();}Private voidSetdone () {IsDone=true; synchronized( This) {//get the lock because the front wait () has freed the callback lock.Notifyall ();//waking up a waiting thread         }}
CallbackexecutortaskStatic Private classCallbackexecutortaskImplementsRunnable {FinalConnectionresponse resp; FinalResponsecallback callback; FinalThread CreateThread; Callbackexecutortask (Connectionresponse _resp, Responsecallback _cb) {resp=_resp; Callback=_CB; CreateThread=Thread.CurrentThread (); }           Public voidrun () {//Prevent this scenario: business-provided executor that allow the caller thread to perform the task             if(CreateThread = =Thread.CurrentThread ()&& callback.getexecutor ()! =diyexecutor.getinstance ()) {StringBuilder SB=NewStringBuilder (); Sb.append ("The network callback task [" + Resp.getrequestid () + "] cancelled, Cause:"); Sb.append ("Can not callback task on the network IO thhread.");                   Logger.warn (Sb.tostring ()); return; }              if(Trconstants.result_success = =Resp.getresult ()) {Callback.handleresponse (Resp.getappresponse ());//set the invocation result             }             Else{callback.onremotingexception (Resp.getresult (), resp. geterrormsg ()); //Handling Call Exceptions             }         }}

Transfer from http://blog.163.com/tsing_hua/blog/static/1396222242012819557547/

Dubbo_ Remote Synchronous Invocation principle

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.