dubbo and zookeeper

For details, please refer to
http://dubbo.io/
http://blog.csdn.net/column/details/learningdubbo.html

Dubbo remote synchronous call principle analysis

In addition , it is explained in the document: Dubbo default protocol uses a single long connection and NIO asynchronous Communication is suitable for small data volume and large concurrent service calls, and the number of service consumer machines is much larger than the number of service provider machines.

Dubbo default protocol, using tbremoting interaction based on mina1.1.7+hessian3.2.1.

Number of connections: single connection
Connection method: long connection
Transmission protocol: TCP
Transmission method: NIO asynchronous transmission
Serialization :
Hessian binary serialization The number of providers is large, and a single consumer cannot overwhelm the provider. Try not to use the dubbo protocol to transmit large files or large strings.
Applicable scenario: conventional remote service method call


Usually, a typical synchronous remote call should be like this:
[Original] Analysis of the principle of synchronous call of Alibaba Dubbo framework-1 - sun - endless learning
1, the client thread calls the remote interface, to the service The client sends a request, and the current thread should be in the "suspended" state, that is, the thread cannot execute backwards, it must get the result given to itself by the server before executing backwards
2. After the server receives the client's request, it processes the request , send the result to client
3, the client receives the result, and then the current thread continues to execute

Dubbo uses Socket (using the apache mina framework as the underlying call) to establish a long connection, send and receive data, and the bottom layer uses the IoSession of the apache mina framework to send messages.

Looking at the Dubbo documentation and source code, it can be seen that the bottom layer of Dubbo uses Socket to send messages for data transmission. Combined with the mina framework, the IoSession.write() method is used. After this method is called, the entire remote call (from sending the request to receiving the result) is called. It is asynchronous, that is, for the current thread, when the request is sent, the thread can be executed later. As for the result of the server, it is sent to the client in the form of a message after the server has completed the processing. So here are 2 questions:
how to make the current thread "pause", and then execute backwards after the result comes back?
As mentioned earlier, Socket communication is a full-duplex method. If there are multiple threads performing remote method calls at the same time, there will be many messages sent by both parties on the socket connection established between the client and server. It may be messy. After the server processes the result, it sends the result message to the client. The client receives a lot of messages. How do you know which message result was called by which thread?
Analysis of the source code, the basic principles are as follows:
A client thread calls the remote interface to generate a unique ID (such as a random string, UUID, etc.), Dubbo uses AtomicLong to accumulate numbers from 0, and
will package the method call information (such as calling The interface name, method name, parameter value list, etc.), and the callback object callback of the processing result are all encapsulated together to form an object object
to put(ID, object) in the global ConcurrentHashMap that specifically stores the call information.
The ID and the packaged method call information are encapsulated into an object connRequest, which is sent out asynchronously using IoSession.write(connRequest)
The current thread then uses the get() method of the callback to try to obtain the result returned by the remote. Inside get(), use synchronized to obtain it. Call back the lock of the callback object, and then first check whether the result has been obtained. If not, then call the wait() method of the callback to release the lock on the callback and make the current thread in a waiting state.
After the server receives the request and processes it, it sends the result (the result contains the previous ID, that is, the return) to the client. The thread on the client's socket connection that monitors the message receives the message, analyzes the result, and gets the ID. , and then get(ID) from the previous ConcurrentHashMap to find the callback, and set the result of the method call to the callback object.
The listening thread then uses synchronized to obtain the lock of the callback object callback (because wait() was called before, the thread has released the lock of the callback), and then notifyAll() to wake up the thread in the waiting state to continue execution (callback get() The method can continue to execute to get the call result), at this point, the whole process is over.
It is necessary to draw a large picture to describe it, and it will be added later. It
should be noted that the callback object here is a new one for each call and cannot be shared, otherwise there will be problems; in addition, the ID must be guaranteed to be in at least one Socket connection. only one.
Now that the first two questions have been answered,
how can the current thread "pause" and execute backwards when the result comes back?
     Answer: First generate an object obj, store it in a global map with put(ID, obj), then use synchronized to acquire the obj lock, then call obj.wait() to make the current thread wait, and then another message listener thread waits until After the server-side result comes, map.get(ID) to find obj, then use synchronized to acquire the obj lock, and then call obj.notifyAll() to wake up the thread in the waiting state.
As mentioned earlier, Socket communication is a full-duplex method. If there are multiple threads performing remote method calls at the same time, there will be many messages sent by both parties on the socket connection established between the client and server. It may be messy. After the server processes the result, it sends the result message to the client. The client receives a lot of messages. How do you know which message result was called by which thread?
     Answer: Use an ID to make it unique, then pass it to the server, and then the server returns it back, so that you know which thread the result belongs to.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326880004&siteId=291194637