我们公司有一个基于Python的网站和一些基于Python的工作节点,它们通过Django / Celery和RabbitMQ进行通信。我有一个基于Java的应用程序,需要向基于Celery的工作人员提交任务。我可以从Java向RabbitMQ发送工作就好了,但Celery的工作人员从不接受工作。从查看两种类型的作业提交的数据包捕获,有差异,但我无法理解如何解释它们因为很多是二进制文件,我找不到有关解码的文档。有没有人对Java / RabbitMQ和Celery一起工作有任何参考或经验?
答案 0 :(得分:12)
我找到了解决方案。 RabbitMQ的Java库引用交换/队列/路由密钥。在Celery中,队列名称实际上映射到Java库中引用的交换。默认情况下,Celery的队列只是“芹菜”。如果您的Django设置使用以下语法定义名为“myqueue”的队列:
CELERY_ROUTES = {
'mypackage.myclass.runworker' : {'queue':'myqueue'},
}
然后基于Java的代码需要执行以下操作:
ConnectionFactory factory = new ConnectionFactory();
Connection connection = null ;
try {
connection = factory.newConnection(mqHost, mqPort);
} catch (IOException ioe) {
log.error("Unable to create new MQ connection from factory.", ioe) ;
}
Channel channel = null ;
try {
channel = connection.createChannel();
} catch (IOException ioe) {
log.error("Unable to create new channel for MQ connection.", ioe) ;
}
try {
channel.queueDeclare("celery", false, false, false, true, null);
} catch (IOException ioe) {
log.error("Unable to declare queue for MQ channel.", ioe) ;
}
try {
channel.exchangeDeclare("myqueue", "direct") ;
} catch (IOException ioe) {
log.error("Unable to declare exchange for MQ channel.", ioe) ;
}
try {
channel.queueBind("celery", "myqueue", "myqueue") ;
} catch (IOException ioe) {
log.error("Unable to bind queue for channel.", ioe) ;
}
// Generate the message body as a string here.
try {
channel.basicPublish(mqExchange, mqRouteKey,
new AMQP.BasicProperties("application/json", "ASCII", null, null, null, null, null, null, null, null, null, "guest", null, null),
messageBody.getBytes("ASCII"));
} catch (IOException ioe) {
log.error("IOException encountered while trying to publish task via MQ.", ioe) ;
}
事实证明,这只是术语上的差异。