Dubbo synchronous asynchronous transfer

  Dubbo RPC middleware is an open source framework, the underlying data transmission used by default Netty, then theoretically handle the request is asynchronous, and why we use is synchronous it? Dubbo framework is certainly done a deal with asynchronous transfer synchronization.

  First, we have to sort out at the asynchronous transfer synchronization, what our needs?

  1, the caller then requests a remote service, you need to wait for the results, at the moment, it should block the request thread

  2, the remote service returns the results, wake-up request thread, the caller get results

  Dubbo synchronous asynchronous transfer, the core class is DefaultFuture, the core is get (), received (Channel channel, Response response).

  DefaultFuture constructor:

. 1      Private  static  Final the Map <Long, Channel> = the CHANNELS new new of ConcurrentHashMap <Long, Channel> ();
 2  
. 3     // every request generates a DefaultFuture object, and then saved to FUTURES, the request return result, based on the id from FUTURES DefaultFuture find the corresponding object, and delete 
. 4      Private  static  Final the Map <Long, DefaultFuture> = FUTURES new new of ConcurrentHashMap <Long, DefaultFuture> ();
 . 5  
. 6      // generated when AtomicLong incremented from 0, created Request object ID 
. 7      Private  Final  Long ID;
 . 8      Private  Final Channel Channel;
 . 9      // request object
10      Private  Final the Request Request;
 . 11      // timeouts 
12 is      Private  Final  int timeout;
 13 is      // used herein Lock and Condition implementation waiting notification mechanism 
14      Private  Final Lock Lock = new new of ReentrantLock ();
 15      Private  Final Condition DONE = lock.newCondition ();
 16      Private  Final  Long Start = System.currentTimeMillis ();
 . 17      Private  volatile  Long Sent;
 18 is      // returns the results of the request 
. 19      Private volatile Response response;
20     private volatile ResponseCallback callback;
21 
22     public DefaultFuture(Channel channel, Request request, int timeout) {
23         this.channel = channel;
24         this.request = request;
25         this.id = request.getId();
26         this.timeout = timeout > 0 ? timeout : channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
27         // put into waiting map.
28         FUTURES.put(id, this);
29         CHANNELS.put(id, channel);
30     }

 

  get():

. 1  public Object GET ( int timeout) throws a RemotingException {
 2          IF (timeout <= 0 ) {
 . 3              timeout = Constants.DEFAULT_TIMEOUT;
 . 4          }
 . 5          // isDone () method is to determine whether there is Response value (i.e., if there results returned) 
6          IF (! {isDone ())
 . 7              Long Start = System.currentTimeMillis ();
 . 8              Lock.lock ();
 . 9              the try {
 10                  the while (! isDone ()) {
 . 11                      // out waiting 
12                     done.await (timeout, TimeUnit.MILLISECONDS);
 13 is                      // if the results returned, or timed out, the loop exits 
14                      IF (isDone () || System.currentTimeMillis () - Start> timeout) {
 15                          BREAK ;
 16                      }
 . 17                  }
 18 is              } the catch (InterruptedException E) {
 . 19                  the throw  new new a RuntimeException (E);
 20 is              } the finally {
 21 is                  lock.unlock ();
 22 is              }
 23 is              // If the overtime, will throw an exception 
24              IF(! IsDone ()) {
 25                  the throw  new new a TimeoutException (Sent> 0, Channel, getTimeoutMessage ( to false ));
 26 is              }
 27          }
 28          // remote service returns normally result is returned to the caller 
29          return returnFromResponse ();
 30      }

 

  received(Channel channel, Response response):

 1 public static void received(Channel channel, Response response) {
 2         try {
 3             // 根据请求id从FUTURES中获取DefaultFuture,并删除
 4             DefaultFuture future = FUTURES.remove(response.getId());
 5             if (future != null) {
 6                 future.doReceived(response);
 7             } else {
 8                 logger.warn("The timeout response finally returned at "
 9                         + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()))
10                         + ", response " + response
11                         + (channel == null ? "" : ", channel: " + channel.getLocalAddress()
12                         + " -> " + channel.getRemoteAddress()));
13             }
14         } finally {
15             // CHANNELS也删除
16             CHANNELS.remove(response.getId());
17         }
18     }
 1 private void doReceived(Response res) {
 2         lock.lock();
 3         try {
 4             response = res;
 5             if (done != null) {
 6                 // 唤醒阻塞的线程
 7                 done.signal();
 8             }
 9         } finally {
10             lock.unlock();
11         }
12         if (callback != null) {
13             invokeCallback(callback);
14         }
15     }

 

  Summary: The principle Dubbo asynchronous transfer synchronization, in fact, is the use of Lock and Condition achieve a wait notification mechanism. Request return result match, then the request is received and implemented by transfer id.

Guess you like

Origin www.cnblogs.com/dushenzi/p/12369955.html
Recommended