RabbitMQ Article 4: Remote Call and rabbitmq Article 4 call

Source: Internet
Author: User

RabbitMQ Article 4: Remote Call and rabbitmq Article 4 call

All we have explained above are local servers. If you need to run a function on a remote computer, wait for the result. This is a different story. This mode is usually called Remote Procedure Call or RPC.

In this chapter, we will use RabbitMQ to build an RPC system, a client, and an extensible RPC server. Now let's get started.

Callback queue

Rpc is generally easier in RabbitMQ. A client sends a request message and a response message to the server. To get a response, we need to send a callback queue address request. As follows:

Message attributes:

The AMQP Protocol has a total of 14 predefined attributes, but most of them are rarely used. The following several attributes may be used more

DeliveryMode: There are two values, one is persistent, the other is short (the second article said)

ContentType: content type: used to describe the MIME type of the encoding. For example, JSON encoding is often used to set this attribute as a good practice: application/json.

ReplyTo: the name of the callback queue is often used.

Correlationid: application related to RPC Response Request

Correlation Id

A response is received in the queue, but it does not know which one the response belongs to. When we use the CorrelationId attribute, we can set it to a unique value for each request, later, when we receive messages in the callback queue, we will see this attribute. If we see an unknown CorrelationId, we can safely ignore the information-it does not belong to our requests. Why should we ignore unknown messages in the callback queue instead of failed errors? This is because of the possibility of a competitive condition on the server side. For example, a confirmation message has not been sent to the request, but the RPC server is down. If this happens, the RPC server will restart again to process the request. This is why repeated responses must be processed on the client.

Requirement

The rpc method is as follows:

1: When the client starts, it creates an anonymous exclusive callback queue.

2: For rpc requests, the client sends two attributes. One is replyTo setting the callback queue, and the other is correlationId setting the unique value for each queue.

3: The request is sent to an rpc_queue queue.

4: The rpc server is a waiting queue request. When receiving a request, the rpc server returns the result returned by the message to the client to end the request.

5: the client waits for data in the callback queue. When a message appears, the client checks the correlationId. If it matches the value returned from the request, the client responds.

Encoding

RPCServer. Java

public class RPCServer {    private static final String RPC_QUEUE_NAME = "rpc_queue";    private static int fib(int n) {        if (n == 0) {            return 0;        }        if (n == 1) {            return 1;        }        return fib(n - 1) + fib(n - 1);    }    public static void main(String[] args) throws IOException, InterruptedException, TimeoutException {        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("localhost");        Connection connection = factory.newConnection();        Channel channel = connection.createChannel();        channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);        channel.basicQos(1);        QueueingConsumer consumer = new QueueingConsumer(channel);        channel.basicConsume(RPC_QUEUE_NAME, false, consumer);        System.out.println("RPCServer Awating RPC request");        while (true) {            QueueingConsumer.Delivery delivery = consumer.nextDelivery();            BasicProperties props = delivery.getProperties();            BasicProperties replyProps = new AMQP.BasicProperties.Builder().                    correlationId(props.getCorrelationId()).build();            String message = new String(delivery.getBody(), "UTF-8");            int n = Integer.parseInt(message);            System.out.println("RPCServer fib(" + message + ")");            String response = "" + fib(n);            channel.basicPublish( "", props.getReplyTo(), replyProps, response.getBytes());            channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);        }    }}

Simple server code

1: establish connections, channels, and queues

2: We may run multiple server processes. To relieve the load on the server, we set channel. basicQos (1 );

3: We use basicconsume to access the queue. Then go to the loop, where we wait for the request message, process the message, and then send a response.

RPCClient. java

public class RPCClient {    private Connection connection;    private Channel channel;    private String requestQueueName = "rpc_queue";    private String replyQueueName;    private QueueingConsumer consumer;    public RPCClient() throws IOException, TimeoutException {        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("localhost");        connection = factory.newConnection();        channel = connection.createChannel();        replyQueueName = channel.queueDeclare().getQueue();        consumer = new QueueingConsumer(channel);        channel.basicConsume(replyQueueName, true, consumer);    }    public String call(String message) throws IOException, InterruptedException {        String response;        String corrID = UUID.randomUUID().toString();        AMQP.BasicProperties props = new AMQP.BasicProperties().builder()                .correlationId(corrID).replyTo(replyQueueName).build();        channel.basicPublish("", requestQueueName, 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;    }    public void close() throws Exception {        connection.close();    }    public static void main(String[] args) throws Exception {        RPCClient rpcClient = null;        String response;        try {            rpcClient = new RPCClient();            System.out.println("RPCClient  Requesting fib(20)");            response = rpcClient.call("20");            System.out.println("RPCClient  Got '" + response + "'");        } catch (Exception e) {            e.printStackTrace();        } finally {            if (rpcClient != null) {                rpcClient.close();            }        }    }}

Client code explanation

1: Establish a connection and channel, and declare the reply of a unique "Callback" queue

2: we subscribe to the callback queue to get the RPC response.

3: Define a call method to send the current callback request.

4: generate a unique correlationid and capture the appropriate response through the while loop.

5: We send two request attributes, replyTo and correlationId.

6: wait until a proper response arrives.

7: The while loop is a very simple task. For each response message, it checks whether there is a correlationid and then performs matching. Then, respond.

8: Finally, return the response to the client.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.