9.RabbitMQ实现RPC

RPC,即远程过程调用,其流程如下:


RPC

RPC实现RPC,则需要客户端(生产者)发送请求消息,服务端(消费者)回复响应的消息,为了接受响应的消息,我们需要在请求消息中发送给一个回调队列。
流程图如下:


RPC流程图

1.客户端启动时,创建一个匿名的回调队列,使用channel.queueDeclare().getQueue()创建一个默认的队列即可
2.客户端为RPC消息创建两个属性,一是ReplyTo即回调队列,二是correlationId,用来将消息和请求匹配。

3.请求被发送到rpc_queue队列中。
4.RPC服务端监听rpc_queue队列中的请求,当请求到来时,服务端会处理,并把带有结果的消息发送给客户端。接受的队列就是replyTo设置的回调队列。
5.客户端监听回调队列,当有消息时,检查correlationId属性,如果与请求匹配,那就是结果。
实现代码如下:

//服务端
public class RPCserver {
    private static final String RPC_QUEUE_NAME="rpc_queue";
    public static void main(String[] args) throws Exception {
        //建立连接
        Connection connection=ConnectionUtil.getConnection();
        Channel channel=connection.createChannel();
        //声明一个队列,该队列用于存储RPC消息
        channel.queueDeclare(RPC_QUEUE_NAME,true,false,false,null);
        //最多消费的信息个数,消费者接受到消息但是还没有向生产者回复确认之前,不会接受新的消息
        channel.basicQos(1);
        System.out.println("Waiting RPC request");
        DefaultConsumer 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="";
                String message=new String(body);
                int n=Integer.parseInt(message);
                //产生回复,n+1
                response=String.valueOf(n+1);
                System.out.println(response);
                channel.basicPublish("",properties.getReplyTo(),replyProps,response.getBytes());
                channel.basicAck(envelope.getDeliveryTag(),false);
            }

        };
        channel.basicConsume(RPC_QUEUE_NAME,false,consumer);

    }
}
public class RPCClient {
    private Connection connection;
    private Channel channel;
    private static final String RPC_QUEUE_NAME="rpc_queue";
    public void creatClient(){
        //获取连接
        try {
            connection=ConnectionUtil.getConnection();
            channel=connection.createChannel();
            //创建匿名的回调队列
            String replyQueueName=channel.queueDeclare().getQueue();
            //生成correlationID,用来判断该消息与哪个请求对应
            final String uuid= UUID.randomUUID().toString();
            AMQP.BasicProperties props=new AMQP.BasicProperties().builder().correlationId(uuid).replyTo(replyQueueName).build();
            String message=String.valueOf(new Random().nextInt(100));
            System.out.println("message:"+message);
            channel.basicPublish("",RPC_QUEUE_NAME,props,message.getBytes());
            //接受返回的结果
            Consumer consumer=new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)
                        throws IOException
                {
                    while (true){
                        if(properties.getCorrelationId().equals(uuid)){
                            String serverResponse=new String(body);
                            System.out.println(" server response:"+serverResponse);
                        }
                        break;
                    }
                }
            };
            channel.basicConsume(replyQueueName,true,consumer);
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
       RPCClient client = new RPCClient();
       client.creatClient();
    }
}

你可能感兴趣的:(9.RabbitMQ实现RPC)