无法让 RabbitMQ Clojure 客户端工作
Cannot have RabbitMQ Clojure client working
我的 RabbitMQ 实例有 2 个客户端,但我无法让 Clojure 版本正常工作。我可能缺少一些 RabbitMQ 配置但不知道是什么。
我的交换是数据,队列是 ALERT。
知道 Clojure 版本中缺少什么吗?
正在工作 Node.js RabbitMQ 客户端
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://192.168.99.100', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'data';
ch.assertExchange(ex, 'direct', {durable: true});
ch.assertQueue('', {exclusive: true}, function(err, q) {
console.log(' [*] Waiting for logs. To exit press CTRL+C');
ch.bindQueue(q.queue, ex, 'ALERT');
ch.consume(q.queue, function(msg) {
console.log(" [x] %s: '%s'", msg.fields.routingKey, msg.content.toString());
}, {noAck: true});
});
});
无法正常工作的 Clojure RabbitMQ 客户端
(ns notifications.core
(:gen-class))
;; Import methods from langohr
(require '[langohr.core :as rmq]
'[langohr.channel :as lch]
'[langohr.queue :as lq]
'[langohr.exchange :as le]
'[langohr.consumers :as lc]
'[langohr.basic :as lb])
(defn start-consumer
"Starts a consumer bound to the given topic exchange in a separate thread"
[ch topic-name]
(let [queue-name "ALERT"
handler (fn [ch {:keys [content-type delivery-tag type] :as meta} ^bytes payload]
(println (format "received %s" (String. payload "UTF-8"))))]
(lq/declare ch queue-name {:exclusive true})
(lq/bind ch queue-name topic-name)
(lc/subscribe ch queue-name handler)))
(defn -main
"Start RabbitMQ consumer"
[& args]
(let [conn (rmq/connect {:host "192.168.99.100"})
ch (lch/open conn)
ex "data"]
(le/declare ch ex "direct" {:durable true})
(start-consumer ch ex)))
更新
在 RabbitMQ 端,我可以看到 Clojure 客户端连接成功,但它没有收到发送到交换数据/队列的消息 "ALERT"。我没有任何错误信息。
在问题的评论中进行更多讨论后,您的客户会这样做:
您的 Node.js 客户端创建 data
直接交换和一个由服务器自动命名的队列,然后它将创建的队列绑定到 data
交换ALERT
路由键。这是一个架构:
exchange:"data" --["ALERT"]--> queue:$generated_name
您的 Clojure 客户端创建 data
直接交换和 ALERT
队列,然后它使用空路由键将创建的队列绑定到 data
交换.
exchange:"data" --[""]--> queue:"ALERT"
您的发布者向 data
交换器发送一条消息,使用 ALERT
作为路由键。因此,在情况 #1 中,消息被正确路由到队列,无论其生成的名称如何,因为路由键与绑定中设置的键匹配。但是,在情况 #2 中,消息被丢弃,因为没有队列绑定到具有匹配路由键的 data
交换。
如果您希望将队列命名为 ALERT
并且希望将具有 ALERT
路由键的消息传送到该队列,您必须使用 ""
交换(它的name 是一个空字符串,路由键表示要使用的队列的名称)或者将 ALERT
队列与 ALERT
路由键绑定。
我的 RabbitMQ 实例有 2 个客户端,但我无法让 Clojure 版本正常工作。我可能缺少一些 RabbitMQ 配置但不知道是什么。 我的交换是数据,队列是 ALERT。
知道 Clojure 版本中缺少什么吗?
正在工作 Node.js RabbitMQ 客户端
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://192.168.99.100', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'data';
ch.assertExchange(ex, 'direct', {durable: true});
ch.assertQueue('', {exclusive: true}, function(err, q) {
console.log(' [*] Waiting for logs. To exit press CTRL+C');
ch.bindQueue(q.queue, ex, 'ALERT');
ch.consume(q.queue, function(msg) {
console.log(" [x] %s: '%s'", msg.fields.routingKey, msg.content.toString());
}, {noAck: true});
});
});
无法正常工作的 Clojure RabbitMQ 客户端
(ns notifications.core
(:gen-class))
;; Import methods from langohr
(require '[langohr.core :as rmq]
'[langohr.channel :as lch]
'[langohr.queue :as lq]
'[langohr.exchange :as le]
'[langohr.consumers :as lc]
'[langohr.basic :as lb])
(defn start-consumer
"Starts a consumer bound to the given topic exchange in a separate thread"
[ch topic-name]
(let [queue-name "ALERT"
handler (fn [ch {:keys [content-type delivery-tag type] :as meta} ^bytes payload]
(println (format "received %s" (String. payload "UTF-8"))))]
(lq/declare ch queue-name {:exclusive true})
(lq/bind ch queue-name topic-name)
(lc/subscribe ch queue-name handler)))
(defn -main
"Start RabbitMQ consumer"
[& args]
(let [conn (rmq/connect {:host "192.168.99.100"})
ch (lch/open conn)
ex "data"]
(le/declare ch ex "direct" {:durable true})
(start-consumer ch ex)))
更新
在 RabbitMQ 端,我可以看到 Clojure 客户端连接成功,但它没有收到发送到交换数据/队列的消息 "ALERT"。我没有任何错误信息。
在问题的评论中进行更多讨论后,您的客户会这样做:
您的 Node.js 客户端创建
data
直接交换和一个由服务器自动命名的队列,然后它将创建的队列绑定到data
交换ALERT
路由键。这是一个架构:exchange:"data" --["ALERT"]--> queue:$generated_name
您的 Clojure 客户端创建
data
直接交换和ALERT
队列,然后它使用空路由键将创建的队列绑定到data
交换.exchange:"data" --[""]--> queue:"ALERT"
您的发布者向 data
交换器发送一条消息,使用 ALERT
作为路由键。因此,在情况 #1 中,消息被正确路由到队列,无论其生成的名称如何,因为路由键与绑定中设置的键匹配。但是,在情况 #2 中,消息被丢弃,因为没有队列绑定到具有匹配路由键的 data
交换。
如果您希望将队列命名为 ALERT
并且希望将具有 ALERT
路由键的消息传送到该队列,您必须使用 ""
交换(它的name 是一个空字符串,路由键表示要使用的队列的名称)或者将 ALERT
队列与 ALERT
路由键绑定。