The use of RabbitMQ under .Net (8) -- remote procedure call RPC

RPC is a common pattern in computing. Usually, I use message queues to implement RPC. There are three key points:

1. Addressing of services

2. Receipt of messages

3. Correlation of messages

 

In RabbitMQ's .net client, two classes are provided: SimpleRpcClient and SimpleRpcServer to allow us to easily develop RPC applications.

Because RabbitMQ's RPC must be based on queues, both the client and the server need a separate queue. The client's queue is used to receive the data replied by the service, and the server's queue is used to cache the Request of the service that needs to be called. These requests must not come from just one client.

The address of the service is public, and the address is also a queue. The client only needs to put the parameters into the queue monitored by the server. Each time the server gets a piece of data from the queue is a call.

The service is not only for a client, so in the parameters of the client call, you need to add the name of the queue to be responded to each time, that is, to tell the server that the result of the method call needs to be placed in this queue. The client can not only put the name of the queue directly in the parameter but also give a route, for example, in the format: exchangeType://exchangeName/routingKey. exchangeType is the type of exchange, choose one of four. The data in this queue is the return value of my calling service. Each client has a queue of such return values. You can view the status of the queue with the following command.

 

image

 

The client may call more frequently, or whether it is calling a method, the return value is different, or the server returns at a different time each time, it cannot be guaranteed that the order of the reply is the same as the order of the client's call. So how does the program guarantee that the return value is the result of this call? RabbitMQ uses CorrelationId, which is an attribute. At each call, the client will generate such an attribute to represent the call. The Id is unique. Of course, the server will also put this Id in the return value and return it together, and the client can use this CorrelationId to pair a call.

If the CorrelationId is not matched during the calling process, the return value message will be discarded without throwing an exception.

A server often provides not only one service (method), but there may be Requests of different methods in a queue. In this case, it is necessary to judge which method is called according to the parameters in each Request. It is common for a service to provide multiple methods and there are obvious drawbacks. If some methods take a long time to be processed by the service, other calls are required to wait. If the server uses multi-threaded processing, then when the client calls, each server method needs a dedicated SimpleRpcClient to call. That is to say, different methods need to have different callback queues, so as to avoid the client will hesitate to match the CorrelationId and discard the message.

 

The sequence of RPC calls is as follows:

1. When the client is initialized, 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. When the connection is disconnected, there is no more.

2. When the client sends a Request, it will add two parameters: ReplyTo and CorrelationId. The former is used to tell the service which queue to put the return value in (callback queue name) or route, and the latter is used to pair each time. Request. Both properties are placed in the accompanying IBasicProperties dictionary that the client sends the message.

3. Put the message into the monitoring queue of the service, and the message naturally has parameters for calling the method.

4. After the service receives the data in the monitored queue, it performs operations and puts the return value into the callback queue specified by the client.

5. After the client sends the Request, it goes to the callback queue created by itself to monitor. If the data is obtained, it will check the CorrelationId in it. If it is consistent with the calling Request, it will return the result.

 

SimpleRpcClient and SimpleRpcServer are just one implementation of RabbitMQ .net client. Knowing the principle, we can also implement the function of RPC ourselves.

 

Load balancing of services

The server often has a queue to receive the client's request. We remember that in this article , we saw the built-in consumer load balancing function of RabbitMQ, so are we suitable for the RPC server? 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 queues are evenly distributed to different servers.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326412996&siteId=291194637