无法让 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"。我没有任何错误信息。

在问题的评论中进行更多讨论后,您的客户会这样做:

  1. 您的 Node.js 客户端创建 data 直接交换和一个由服务器自动命名的队列,然后它将创建的队列绑定到 data 交换ALERT 路由键。这是一个架构:

    exchange:"data" --["ALERT"]--> queue:$generated_name
    
  2. 您的 Clojure 客户端创建 data 直接交换和 ALERT 队列,然后它使用空路由键将创建的队列绑定到 data 交换.

    exchange:"data" --[""]--> queue:"ALERT"
    

您的发布者向 data 交换器发送一条消息,使用 ALERT 作为路由键。因此,在情况 #1 中,消息被正确路由到队列,无论其生成的名称如何,因为路由键与绑定中设置的键匹配。但是,在情况 #2 中,消息被丢弃,因为没有队列绑定到具有匹配路由键的 data 交换。

如果您希望将队列命名为 ALERT 并且希望将具有 ALERT 路由键的消息传送到该队列,您必须使用 "" 交换(它的name 是一个空字符串,路由键表示要使用的队列的名称)或者将 ALERT 队列与 ALERT 路由键绑定。