关于java和python同时使用rabbitmq时队列同名问题的探讨
问题引出:
我们知道,进程之间是不能直接通信的,但是今天学习rabbitmq时发现一个奇怪的问题,即当我开启rabbitmq,用java写好的代码给rabbitmq发送完消息后并没有急着使用java去消费消息,转而使用python写好的代码来消费消息,发现python程序完美的接收到来自java程序发出的消息
问题分析:
rabbitmq是用elang语言编写的适用于多平台的一款应用程序,我们使用代码去连接rabbitmq时相当于使用了某种连接手段达成rabbitmq和该程序之间的通信,socket底层是如何具体封装的我们不得而知,但我们可以知道socket编程就是一种实现进程间通信的手段,我想大概rabbimqt和python程序的通信就是采用的这种方式吧。由此,我们想到了进程通信的实现手段之一:客户端----》服务器---》客户端模型,所以看到java发送的消息能够在python程序中消费掉绝非偶然,而是必然。所以可以使用一个中间代理(RabbitMQ),实现不同进程之间的通信。由此,不同进程之间的通信得以解决
java生产方代码(Productor.java):
1 package RabbitMQTest; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 import com.rabbitmq.client.AMQP.Queue; 6 import com.rabbitmq.client.Channel; 7 import com.rabbitmq.client.Connection; 8 import com.rabbitmq.client.ConnectionFactory; 9 10 public class Productor { 11 public static String QUEUE_NAME = "hello"; 12 public static void main(String[] args) { 13 //初始化socket链接 14 ConnectionFactory factory = new ConnectionFactory(); 15 //指定链接地址 16 factory.setHost("localhost"); 17 try{ 18 //建立程序和rabbitmq的socket连接 19 Connection connection = factory.newConnection(); 20 //创建管道 21 Channel channel = connection.createChannel(); 22 //声明队列 23 channel.queueDeclare(QUEUE_NAME,false,false,false,null); 24 //让当前线程睡眠8s,以检验rabbitmq的消息轮询 25 //Thread.currentThread().sleep(8000); 26 String message = "hello,world"; 27 //发送消息 28 channel.basicPublish("", QUEUE_NAME, null, message.getBytes()); 29 System.out.println("[x] send the message"+message); 30 channel.close(); 31 connection.close(); 32 }catch (Exception e) { 33 System.out.println("程序出错:"+e); 34 } 35 } 36 }
python消费方代码(Consumer.py):
1 # __author__ = 'STEVEN' 2 import pika 3 #创建socket链接 4 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) 5 #创建管道 6 channel = connection.channel() 7 #创建队列 8 channel.queue_declare('hello') 9 #声明回调函数 10 def callback(ch,method,properties,body): 11 print('[x] recieved message%r'%body.decode()) 12 #如果接受到消息就调用回调函数,准备接受消息 13 channel.basic_consume(callback,queue='hello',no_ack=True) 14 print('[*] is waiting for recieve mess press ctrl+c to eixt') 15 #开始消费消息 16 channel.start_consuming()
保证java发送的数据能被python接收到的前提条件:
两者声明消息队列时采用的队列名称必须一致,本例中都是queue_name = "hello"