(Transfer + share) Simple RPC service based on the message middleware RabbitMQ / MarkerHub April 8th MarkerHub April 8th

Little Hub reads:

Based on RabbitMq, how to make an RPC framework, take a look at the code, you should be able to understand it!

RPC (Remote Procedure Call) is a computer communication protocol. For two machines, the application on server A calls the function or method on server B. Since they are not running on the same memory space or machine, network communication is needed.

1. RPC framework

We first understand the workflow of RPC through a picture:

Therefore, to implement the simplest RPC service, only Client, Server and Network are needed. This article uses the message middleware RabbitMQ as the carrier of the Network to transmit information and implement a simple RPC service. The simple principle can be shown in the figure below:

That is: when the client sends an RPC request, the client is the message producer and the server is the message consumer; when the server returns the result, the server is the message producer, and the client is the message consumer; different queues are used for sending and returning.

Next, we use the code to show in detail an RPC service that calculates the Fibonacci sequence.

2. RPCServer implementation

2.1 Server initialization

Initialization is to declare RabbitMQ link factories, links, channels, queues, switches, etc., and bind them to form the AMQP communication structure.

2.2 Listen to the queue and feedback

	
	
		/**

		* 开启server

		*/

		private void startServer() {

		try {

				LOG.info("Waiting for RPC calls.....");

				while (true) {
			
					//获得文本消息
			
					QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			
					BasicProperties props = delivery.getProperties();
			
			
					//返回消息的属性
			
					BasicProperties replyProps = new BasicProperties.Builder().correlationId(props.getCorrelationId()).build();
			
					long receiveTime = System.currentTimeMillis();
			
					JSONObject json = new JSONObject();
	
					try {
			
							String message = new String(delivery.getBody(), "UTF-8");
					
							int n = Integer.parseInt(message);
					
							LOG.info("Got a request: fib(" + message + ")");
					
							json.put("status", "success");
					
							json.put("result", fib(n));
			
					} catch (Exception e) {
				
							json.put("status", "fail");
					
							json.put("reason", "Not a Number!");
					
							LOG.error("receive message failed!", e);
			
					} finally {
			
							long responseTime = System.currentTimeMillis();
					
							json.put("calculateTime", (responseTime - receiveTime));
					
							channel.basicPublish("", props.getReplyTo(), replyProps, json.toString().getBytes("UTF-8"));
					
							channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
			
					}
		
				}
		
			} catch (Exception e) {
	
				LOG.error("server failed!", e);
	
			} finally {
	
				if (connection != null) {
		
					try {
			
						connection.close();
			
					} catch (Exception e) {
			
						LOG.error("close failed!", e);
			
					}
		
				}
		
			}

		}

An infinite loop is used in this method, processing one message at a time. Get the latest message in the RabbitMQ queue by calling the nextDelivery method of the consumer object. At the same time, get the feedback information attribute in the message through getProperties, which is used to mark the attributes of the client. Then calculate the result of the Fibonacci sequence.
Finally, basicAck used the message envelope to confirm the message to RabbitMQ.

At this point, the server side of the RPC service for calculating Fibonacci sequence is realized.

3. RPCClient implementation

3.1 Initialize CLIent

The way to declare the AMQP structure here is similar to that of the Server side, except that the Client side needs to declare an additional queue for the RPC response.

3.2 Send/receive messages


		/**

		* 请求server

		* @param message

		* @return

		* @throws Exception

		*/

		private String requestMessage(String message) throws Exception {

			String response = null;
	
			String corrId = UUID.randomUUID().toString();
	
			BasicProperties props = new BasicProperties.Builder().correlationId(corrId).replyTo(RESPONSE_QUEUE).build();
	
			channel.basicPublish("", QUEUE_NAME, props, message.getBytes("UTF-8"));
	
			while (true) {
	
				QueueingConsumer.Delivery delivery = consumer.nextDelivery();
		
				if (delivery.getProperties().getCorrelationId().equals(corrId)) {
		
					response = new String(delivery.getBody(),"UTF-8");
		
					break;
				}
			}
			return response;

		}

BasicProperties is used to store the properties of your request message. Here I set the correlationId and replyTo properties for the return identification on the Server side.

4. Run the test

Client side sends:

The Server side receives and processes:

Client receives the calculation result:

Since the server where I run RabbitMQ is rented by Alibaba Cloud, the transmission delay is about 60ms. If the RPC service and message middleware are deployed in the same computer room, the delay is basically at the ms level.

5. FAQ

5.1 Description

To experience the complete process, you need the following environment:

JDK1.6以上 + Maven+ RabbitMQ

5.2 Source code

Please poke the complete code: github: https://github.com/chadwick521/rabbitmqdemo

The code of Server is in:

rpc.RPCServer

The code location on the Client side:

rpc.RPCClient

The above content is all about implementing a simple RPC service based on the message middleware RabbitMQ. Thank you for reading here!

 

                                     ------------------------------------------- < END >---------------------------------------

Author: zhaoyh

Original address https://blog.csdn.net/ZYH920521/article/details/88974607

MarkerHub article index: (click to read the original text directly)

https://github.com/MarkerHub/JavaIndex

MarkerHub  April 8

 

Guess you like

Origin blog.csdn.net/qq_31653405/article/details/107205780