RabbitMQ usage scenario exercise: RPC (7)

  • RPC, synchronous message
     The default consumer of RabbitMQ is asynchronous listening. RPC applications need to realize the synchronization of consumers. You can use QueueingConsumer (inherited from DefaultConsumer, which defines a blocking queue LinkedBlockingQueue) to achieve synchronization.
     In fact, the server and the client each define a message queue and send messages to each other. , the client synchronously waits for the result to return after sending the message

  • Points to Note

Specify the reply queue, corrId when sending a message :
//Send a message, specifying the queue where the reply message is located
BasicProperties props=new BasicProperties.Builder().correlationId(corrId).replyTo(queueName).build();
channel.basicPublish("", "rpc_queue", props, SerializationUtils.serialize(mes));

Listen to the queue and wait for server feedback (blocking) :
//Listen to the queue and receive the server reply message
 while(true){
     QueueingConsumer.Delivery delivery=consumer.nextDelivery();//堵塞	  
     //do something
     break;
 }

After receiving the message, the server writes back the processing result :
channel.basicPublish("", properties.getReplyTo() ,new BasicProperties.Builder().correlationId(properties.getCorrelationId()).build(),
						SerializationUtils.serialize("response:"+mes));

The server enables manual answering :
//Turn off the automatic response mechanism, which is enabled by default; at this time, you need to manually perform the response
channel.basicConsume("rpc_queue", false, consumer);
channel.basicAck(envelope.getDeliveryTag(), false);

Limit the maximum processing capacity of the server :
channel.basicQos(1);

  • RPC server

package com.demo.mq.rabbitmq.example06;

import java.io.IOException;
import java.io.Serializable;

import org.apache.commons.lang3.SerializationUtils;

import com.demo.mq.rabbitmq.MqManager;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

/**
 * RPC server
 * @author sheungxin
 *
 */
public class RPCServer{

	/**
	 * RPC server, declare a service processing queue, after receiving the message processing, write the result back to the client
	 * The manual response mechanism needs to be turned on to ensure that the service execution is completed
	 * @param object message body
	 * @throws IOException
	 */
	public static void sendAToB(Serializable object) throws Exception{
		Connection conn=MqManager.newConnection();
		Channel channel=conn.createChannel();
		channel.queueDeclare("rpc_queue", false, false, false, null);
		channel.basicQos(1);
		
		Consumer consumer=new DefaultConsumer(channel){
			@Override
			public void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) throws IOException{
				String mes=SerializationUtils.deserialize(body);
				System.out.println(envelope.getRoutingKey()+":Received :'"+mes+"' done");
				//After receiving the message, write back the message to the sender: specify the queue where the sender is located (properties.getReplyTo()), correlationId
				channel.basicPublish ("", properties.getReplyTo (),
						new BasicProperties.Builder().correlationId(properties.getCorrelationId()).build(),
						SerializationUtils.serialize("response:"+mes));
				channel.basicAck(envelope.getDeliveryTag(), false);
			}
		};
		//Turn off the automatic response mechanism, which is enabled by default; at this time, you need to manually perform the response
		channel.basicConsume("rpc_queue", false, consumer);
		System.out.println("*********8");
	}
	
	public static void main(String[] args) throws Exception {
		sendAToB("Hello World !");
	}
}

  • RPC client

package com.demo.mq.rabbitmq.example06;

import java.util.UUID;

import org.apache.commons.lang3.SerializationUtils;

import com.demo.mq.rabbitmq.MqManager;
import com.rabbitmq.client.AMQP.BasicProperties;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

/**
 * RPC client
 * @author sheungxin
 *
 */
@SuppressWarnings("deprecation")
public class RPCClient {
	
	/**
	 * RPC client: send a message to the server processing queue, specify correlationId and reply queue name when sending, and establish a consumer on the reply queue to monitor and receive reply messages
	 * @param month
	 * @throws Exception
	 */
	public static String call(String mes) throws Exception{
		String response=null;
		Connection conn=MqManager.newConnection();
		Channel channel=conn.createChannel();
		//Create a temporary queue for receiving reply messages
		String queueName=channel.queueDeclare().getQueue();
		QueueingConsumer consumer=new QueueingConsumer(channel);
		channel.basicConsume(queueName, true, consumer);
		
		String corrId=UUID.randomUUID().toString();
		//Send a message, specifying the queue where the reply message is located
		BasicProperties props=new BasicProperties.Builder().correlationId(corrId).replyTo(queueName).build();
		channel.basicPublish("", "rpc_queue", props, SerializationUtils.serialize(mes));
		
		//Listen to the queue and receive the server reply message
		while(true){
			QueueingConsumer.Delivery delivery=consumer.nextDelivery();
			if(delivery.getProperties().getCorrelationId().equals(corrId)){
				response=SerializationUtils.deserialize(delivery.getBody());
				break;
			}
		}
		return response;
	}
	
	public static void main(String[] args) throws Exception {
		System.out.println(call("hello world"));
		System.out.println("waiting for rpc is over");
	}

}

Guess you like

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