RPC is a common mode in computing. Generally, there are three key points for implementing RPC using message queues:
1. Service addressing
2. receive messages
3. Message Association
In rabbitmq's. Net client, two classes are provided: simplerpcclient and simplerpcserver, so that we can easily develop RPC applications.
Because the RPC of rabbitmq must be queue-based, a separate queue is required between the client and the server. The queue of the client is used to receive service reply data, the server Queue is used to cache the request of the service to be called. These requests must not come from a client alone.
The service address is public, and the address is a queue. The client only needs to put the parameters in the queue monitored by the server. Each time the server obtains data from the queue, it is called.
The service is not just a client service, so in the parameters called by the client, the queue name to be replied needs to be added each time, that is, to tell the server that the method call result needs to be placed in this queue. The client can not only directly put the queue name in the parameter, but also provide a route, such as the format: exchangetype: // exchangename/routingkey. Exchangetype is the type of exchange. The data in this queue is the returned value of the service I call. Each client has a returned value queue. You can run the following command to view the queue information.
The client may call a method frequently, or call a method with different return values, or the time returned by the server each time is different. The reply sequence cannot be consistent with the client call sequence. SoProgramHow can we ensure that the returned value is the result of this call? Rabbitmq uses correlationid, which is an attribute. During each call, the client will generate such an attribute to represent this call. The ID is unique. Of course, the server will also put this ID in the returned value and return it together. This client can use this correlationid to pair a call.
If the correlationid is not matched during the call, the returned message is discarded without throwing an exception.
A server usually provides more than one service (method). In a queue, there may be different request methods, in this case, you need to determine which method to call based on the parameters in each request. A service provides multiple methods and has obvious drawbacks. If some methods are processed for a long time, other calls are required. If the server uses multiple threads, a dedicated simplerpcclient is required to call each server method during client calls. In other words, different methods need different callback queues to avoid the client from hesitating to match correlationid and discarding messages.
The RPC call sequence is as follows:
1. During client initialization, that is, when the simplerpcclient class is initialized, it will randomly create a callback queue to store the return value of the service. This queue is exclusive. The connection is disconnected.
2. when sending a request, the client adds two parameters: replyto and correlationid. The former is used to tell the queue in which the service return value is stored (the queue name of callback) or the route, the latter is used to pair each request. Both attributes are stored in the ibasicproperties dictionary attached to the client to send messages.
3. Put the message into the monitoring queue of the service. The message contains parameters for calling methods.
4. After receiving data in the monitored queue, the Service performs operations and puts the returned values into the callback queue specified by the client.
5. After the client sends the request, it listens to the self-created callback queue. If data is obtained, it will view the correlationid in it. If it is consistent with the called request, it will return the result.
Simplerpcclient and simplerpcserver are only implementations of the rabbitmq. Net client. Now that we know the principle, we can implement the RPC function by ourselves.
Service Load Balancing
The server usually has a queue to receive client requests. In this article, we can see the consumer load balancing function built in rabbitmq. For the RPC server, is it suitable for us? The answer is yes. Because our RPC server is actually a worker, we only need to run multiple servers that monitor the same queue. All requests in the monitored queue are evenly distributed to different servers.
You can click here to download the RPC exampleCode.