RabbitMQ的RPC【JAVA】

本文介绍了在RabbitMQ中实现RPC的原理和步骤,包括客户端和服务器端的代码实现。讨论了如何处理分布式事务和并发问题,强调了线性处理消息的特性。同时指出,可以通过设置`auto_ack`和使用独立的`channel`来解决并发处理。最后,提供了修改后的服务器代码,展示了如何利用线程并发处理RPC请求。
摘要由CSDN通过智能技术生成

使用RabbitMQ的RPC

笔者不才,根据小弟的经验觉得使用rabbitMQ进行RPC调研不太妥当,需要他能够实现跨语言,但是对于整体来说使用消息队列服务进行RPC调用,通过RabbitMQ的事务来确定消息已经成功处理完毕,然后通过消息队列服务的reply队列返回处理结果。总觉得差点什么,或者你跟我一样发现了一些问题。第一如何处理分布式事务,这个的确有点费解,这个后面在spring和JPA的时候再去说吧。第二个问题也是我还没有弄懂的一个问题,就是如何做到多线程并发处理。

为什么我会提出这个问题,因为根据rabbitMQ的消息队列处理机制当中,消息队列在消息没有ack之前他是不会继续分发消息的,所以同一时间内你只能处理一条消息,也代表你处理的消息是线性的。再看WEB程序,大家都清楚在Servlet 被调用的时候会新开一条线程,然后在独立的线程去调用serivce 或 dao 等等的业务,也证明了WEB服务是多线程去处理的,而非线性的,总不能一个人在调用这个链接之后,下一个用户也调用这个链接就卡住那里等着吧?所以对于消息队列这种线性的处理方式,我们应该怎么去做到并发呢?方法有能多种,设置成no_ack 然后每次接收到消息之后开启性的线程去处理。第二种方法也是比较简单的开多几个channel,这样就形成多个消费者了。不过以上两个想法,只是我想象而已,也没有实践过,不过今天在写这个东西的时候,我打算实践一下。而且我会在这个笔记当中记录RabbitMQ 的RPC 调用方式。

本人参考的文档为官网关于RPC的介绍:

http://www.rabbitmq.com/tutorials/tutorial-six-java.html

本次我开发所使用的语言为JAVA,在动手写代码之前先说明几个重点问题。

在RabbitMQ 实现RPC的原理

在rabbitMQ上实现RPC,与之前的订阅消息和生产消息非常相似,唯一不一样的是RPC需要消息处理的放回结果,当然有时你不需要结果,你只在乎是否执行成功而已,但是这里所涉及的问题是我们怎样能做到当消息发送到队列之后,开始等待直到消息处理完成后返回处理结果后再进行执行其他处理。

引用一下官方的图,真心画的不错。

这里写图片描述

在到这个图基本上都清晰了。
1. client发起消息,然后带上一个唯一的correlation_id,同时在reply_to中提供一个独立的队列。官方一般建议使用默认独立。后面会有代码~
2. 携带好correlation_id 和 reply_to 之后将消息发布。
3. 然后server 获得消息,并处理消息。
4. 得出的处理结果通过 reply_to 中的队列 返回消息 并携带上 消息中携带的的correlation_id。
5. client 监听 reply_to 队列,当获得消息后,判断消息中correlation_id 是否与请求时发出的一致,如果一致就证明该消息是这个业务的处理结果。如果不一致就证明消息不是你的啦~ 别碰人家的东西!

贴出官方的summary:

  1. When the Client starts up, it creates an anonymous exclusive callback queue.【当Client运行时,创建一个匿名的 独立的 回调队列】
  2. For an RPC request, the Client sends a message with two properties: replyTo, which is set to the callback queue and correlationId, which is set to a unique value for every request. 【client 发送的消息 会携带两个参数是为了 RPC调用的,replyTo 是设置回调的队列,correlation 是 唯一的数值,不同的请求就不同的correlationID】
  3. The request is sent to an rpc_queue queue. [发送消息到队列当中]
  4. The RPC worker (aka: server) is waiting for requests on that queue. When a request appears, it does the job and sends a message with the result back to the Client, using the queue from the replyTo field.【worker 即是服务器 等待队列中的消息,当请求出现时,开始干活同时通过replyTo字段中的队列发送处理结果】
  5. The client waits for data on the callback queue. When a message appears, it checks the correlationId property. If it matches the value from the request it returns the response to the application.【client 等待数据返回的队列,当有消息出现时,检查corrleationID 参数,如果和之前发出的correlationid吻合,就将结果返回到应用程序】
实现代码如下

Client 如下:

package com.maxfunner.rpc;

import com.rabbitmq.client.*;
import org.apache.commons.lang.SerializationUtils;

import java.io.IOException;
import java.util.UUID;

/**
 * Created by Tony on 2016/11/3.
 */
public class Client {
   


    public String sayHelloToServer(String username) throws IOException, InterruptedException {

        String exchangeName = "rpc_exchange";   //交换器名称
        String queueName = "rpc_queue";     //队列名称
        String routingKey = "rpc_key";  //路由键

        ConnectionFactory factory = new ConnectionFactory();
        factory.setVirtualHost("test");
        factory.setHost("192.168.0.21");
        factory.setPort(5673);
        factory.setUsername("tony");
        factory.setPassword("tonypwd");     //创建链接

        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();   

        channel.exchangeDeclare(exchangeName, "direct", false, false, null);    //定义交换器

        channel.queueDeclare(queueName, false, false, false, null); //定义队列

        channel.queueBind(queueName, exchangeName, routingKey, null); //绑定队列

        String callbackQueue = channel.queueDeclare().getQueue();   //获得匿名的 独立的 默认队列

        String correlationId = UUID.randomUUID().toString();    //产生一个 关联ID correlationID

        QueueingConsumer consumer = new QueueingConsumer(channel);  // 创建一个消费者对象

        channel.basicConsume(callbackQueue,true,consumer);      //消费消息

        AMQP.BasicProperties basicProperties = new AMQP.BasicProperties.Builder()   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值