八、rabbitMQ RPC

来源:互联网 发布:centos 7iso镜像安装 编辑:程序博客网 时间:2024/06/07 19:28

前面的章节我们学习的都是生产者发送数据,消费者处理数据,但是数处理的结果生产者并知道。现在是大数据是时代,我们希望a机器收集到数据后交个b机器去运算,这种运算是十分耗时的,b机器运算后把结果再给a机器。

这种模式我们称为:RPC(Remote Procedure Call Protocol)远程过程调用。


a机器将数据放到指定的队列中,b机器从队列中获取数据,数据处理完成后将数据放入a机器指定的队列中,a机器同过reply_to 这个参数告诉b机器放到哪个队列中。这其中就会出现一个问题:a机器可能有很多,每个a机器同一时间可能会发送多个数据给b机器去数据,b机器结果存放队列中会存放多个处理结果。原数据和数据处理结果如何匹配?

a机器发送的每个数据我们都给他唯一的标识,处理结果同样也打上这个标识,correlation_id用来存放该标识。

a机器:

package test1;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Channel;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Envelope;import java.io.IOException;import java.util.UUID;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeoutException;public class RPCClient {    private Connection connection;    private Channel channel;    private String requestQueueName = "rpc_queue";    private String replyQueueName;    public RPCClient() throws IOException, TimeoutException {        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("localhost");        connection = factory.newConnection();        channel = connection.createChannel();        replyQueueName = channel.queueDeclare().getQueue();    }    public String call(String message) throws IOException, InterruptedException {      final   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"));        final BlockingQueue<String> response = new ArrayBlockingQueue<String>(1);        channel.basicConsume(replyQueueName, true, new DefaultConsumer(channel) {            @Override            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {                if (properties.getCorrelationId().equals(corrId)) {                    response.offer(new String(body, "UTF-8"));                }            }        });        return response.take();    }    public void close() throws IOException {        connection.close();    }    public static void main(String[] argv) {        RPCClient fibonacciRpc = null;        String response = null;        String data="30";        try {            fibonacciRpc = new RPCClient();            System.out.println("需要计算的大数据:"+data);            response = fibonacciRpc.call(data);            System.out.println("大数据计算结果:"+response);        }        catch  (Exception e) {            e.printStackTrace();        }        finally {            if (fibonacciRpc!= null) {                try {                    fibonacciRpc.close();                }                catch (IOException _ignore) {}            }        }    }}

b机器代码

package test1;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Consumer;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Envelope;import java.io.IOException;public class RPCServer {    private static final String RPC_QUEUE_NAME = "rpc_queue";    private static int fun(int n) throws Exception {        Thread.sleep(n * 1000);//数据越大处理时间越长        return n * n;    }    public static void main(String[] argv) {        ConnectionFactory factory = new ConnectionFactory();        factory.setHost("localhost");        Connection connection = null;        try {            connection = factory.newConnection();            final Channel channel = connection.createChannel();            channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null);            channel.basicQos(1);            System.out.println("等待 RPC requests");            Consumer consumer = new DefaultConsumer(channel) {                @Override                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {                    AMQP.BasicProperties replyProps = new AMQP.BasicProperties                            .Builder()                            .correlationId(properties.getCorrelationId())                            .build();                    String response = "";                    try {                        String message = new String(body, "UTF-8");                        int n = Integer.parseInt(message);                        System.out.println("收到数据:" + n);                        System.out.println("正在处理>>>");                        response = fun(n) + "";                        System.out.println("处理完成。");                    } catch (Exception e) {                    } finally {                        channel.basicPublish("", properties.getReplyTo(), replyProps, response.getBytes("UTF-8"));                        channel.basicAck(envelope.getDeliveryTag(), false);                    }                }            };            channel.basicConsume(RPC_QUEUE_NAME, false, consumer);            while (true) {                try {                    Thread.sleep(100);                } catch (InterruptedException _ignore) {                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (connection != null)                try {                    connection.close();                } catch (IOException _ignore) {                }        }    }}








原创粉丝点击