簡體   English   中英

如何動態地將消息路由到RabbitMQ中的隊列

[英]How to dynamically route message to queues in RabbitMQ

我想開發可以動態地將消息路由到不同隊列(超過10000個隊列)的解決方案。 到目前為止,這就是我所擁有的:

  • 交換類型設置為topic 這樣我就可以根據路由鍵將消息路由到不同的隊列。
  • 10000個路由鍵為#.%numberOfQueue.#隊列。 %numberOfQueue%是該隊列的簡單數字值(但可能會更改為更有意義的值)。
  • 生產者產生帶有路由鍵的消息,例如: 5.10.15.105.10000 ,這意味着消息應被路由到具有鍵5、10、15、105和10000的鍵,因為它們構成了該隊列的模式。

從Java客戶端API來看就是這樣:

String exchangeName = "rabbit.test.exchange";
String exchangeType = "topic";
boolean exchangeDurable = true;
boolean queueDurable = true;
boolean queueExclusive = false;
boolean queueAutoDelete = false;
Map<String, Object> queueArguments = null;

for (int i = 0; i < numberOfQueues; i++) {
    String queueNameIterated = "rabbit.test" + i + ".queue";
    channel.exchangeDeclare(exchangeName, exchangeType, exchangeDurable);
    channel.queueDeclare(queueNameIterated, queueDurable, queueExclusive, queueAutoDelete, queueArguments);

    String routingKey = "#." + i + ".#";
    channel.queueBind(queueNameIterated, exchangeName, routingKey);
}

這就是為從0到9998的隊列的所有消息生成routingKey

private String generateRoutingKey() {
    StringBuilder keyBuilder = new StringBuilder();
    for (int i = 0; i < numberOfQueues - 2; i++) {
        keyBuilder.append(i);
        keyBuilder.append('.');
    }
    String result = keyBuilder.append(numberOfQueues - 2).toString();
    LOGGER.info("generated key: {}", result);
    return result;
}

看起來不錯。 問題是我不能在channel.basicPublish()方法中使用這么長的routingKey

線程“主”中的異常java.lang.IllegalArgumentException:短字符串太長; utf-8編碼長度= 48884,最大= 255. com.rabbitmq.client.impl.ValueWriter.writeShortstr(ValueWriter.java:50)at com.rabbitmq.client.impl.MethodArgumentWriter.writeShortstr(MethodArgumentWriter.java:74)在com.rabbitmq.client.impl.AMQImpl $ Basic $ Publish.writeArgumentsTo(AMQImpl.java:2319)在com.rabbitmq.client.impl.Method.toFrame(Method.java:85)在com.rabbitmq.client.impl com.rabbitmq.client.impl.AMQChannel.quiescingTransmit(AMQChannel.java:396)處的com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:372)處的.AMQCommand.transmit(AMQCommand.java:104) com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:672)上的com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:690)com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:672)在com.rabbitmq.client.impl.recovery.AutorecoveringChannel.basicPublish(AutorecoveringChannel.java:192)處的ChannelN.java:662)

我有要求:

  • 從生產者動態選擇隊列在其中產生消息的生產者。 它可能只是一個隊列,所有隊列或1000個隊列。
  • 我有10000多個不同的隊列,可能需要向它們產生相同的消息。

所以問題是:

  1. 我可以使用這么長的鑰匙嗎? 如果可以-怎么做?
  2. 也許我可以通過不同的exchange或隊列配置來實現相同的目標?
  3. 也許有一些哈希函數可以有效地區分目標並將其折疊為255個符號? 如果是這樣,它應該提供處理不同出版物的方法(例如,如何僅發送到編號為555和8989的隊列?)?
  4. 也許可以通過這種方式使用一些不同的關鍵策略?
  5. 我還能如何達到要求?

我不久前才開始使用RabbitQM,希望仍然可以為您提供幫助。 路由密鑰中可以包含任意數量的單詞,最多255個字節(也如RabbitMQ教程5-主題中所述 )。 因此,主題交換似乎不適用於您的用例。

也許您可以在這種情況下使用標頭交換 根據概念描述:

標頭交換旨在用於在多個屬性上路由,這些屬性比路由鍵更容易表示為消息標頭。 標頭交換忽略路由鍵屬性。 相反,用於路由的屬性取自headers屬性。 如果標頭的值等於綁定時指定的值,則認為消息匹配。

參見此處此處的示例。 就像我說的那樣,我只是從RabbitMQ開始的,因此,我不確定這是否適合您。 如果以后有時間,我會嘗試為您構建一個簡單的示例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM