Кролик экономит лишние байты для сообщений AMQP 1.0 - PullRequest
0 голосов
/ 12 февраля 2019

У меня есть среда, в которой некоторым клиентам AMQP 1.0 и некоторым клиентам AMQP 0.9.1 необходимо писать / читать из очереди RabbitMQ.Я включил плагин AMQP 1.0 rabbit и он работает, но я получаю дополнительные байты в теле для каждого сообщения AMQP 1.0.

Я отправляю сообщения через AMQP1.0 с помощью rhea (машинопись):

const connection: Connection = new Connection (
  {
    host: 'localhost',
    port: 5672,
    id: 'my_id',
    reconnect: true
  }
);

const senderName = "sender01";
const senderOptions: SenderOptions = {
  name: senderName,
  target: {
    address: "target.queue"
  },
  onError: (context: EventContext) => {},
  onSessionError: (context: EventContext) => {}
};

await connection.open();
const sender: Sender = await connection.createSender(senderOptions);
sender.send({
  body: JSON.stringify({"one": "two", "three": "four"}),
  content_encoding: 'UTF-8',
  content_type: 'application/json'
});
console.log("sent");
await sender.close();

await connection.close();
console.log("connection closed");

Этот пример работает, но это то, что хранится в очереди:

enter image description here

Кодированное в base64 сообщение AFN3oRx7Im9uZSI6InR3byIsInRocmVlIjoiZm91ciJ9, который после декодирования становится:

Sw{"one":"two","three":"four"}

Существует еще один Sw, который я не отправил.

Я попытался настроить клиент Java с официальной библиотекой RabbitMQ (которая говоритAMQP 0.9.1), чтобы увидеть, были ли отправлены эти дополнительные байты клиентам:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.basicConsume(
  "target.queue",
  true,
  (consumerTag, delivery) -> {
    String message = new String(delivery.getBody(), "UTF-8");
    System.out.println(" [x] Received '" + message + "'");
  },
  ignored -> {}
);

Это вывод:

 [x] Received ' Sw�{"one":"two","three":"four"}'

Странная вещь в том, что если я пытаюсь потреблять точноето же самое сообщение с клиентом AMQP 1.0, эти дополнительные байты не появляются в теле полученного сообщения, дополнительные байты появляются только при публикации с AMQP 1.0 и подписке с AMQP 0.9.1.

Почему это так?Есть ли способ избежать лишних байтов при использовании обеих версий AMQP?


ОБНОВЛЕНИЕ

Я также пробовал с SwiftMQ:

int nMsgs = 100;

int qos = QoS.AT_MOST_ONCE;
AMQPContext ctx = new AMQPContext(AMQPContext.CLIENT);
String host = "localhost";
int port = 5672;
String queue = "target.queue";

try {

  Connection connection = new Connection(ctx, host, port, false);
  connection.setContainerId(UUID.randomUUID().toString());
  connection.setIdleTimeout(-1);
  connection.setMaxFrameSize(1024 * 4);
  connection.setExceptionListener(Exception::printStackTrace);
  connection.connect();
  {

    Session session = connection.createSession(10, 10);
    Producer p = session.createProducer(queue, qos);
    for (int i = 0; i < nMsgs; i++) {
      AMQPMessage msg = new AMQPMessage();
      System.out.println("Sending " + i);
      msg.setAmqpValue(new AmqpValue(new AMQPString("{\"one\":\"two\",\"three\":\"four\"}")));
      p.send(msg);
    }
    p.close();
    session.close();
  }
  connection.close();
} catch (Exception e) {
  e.printStackTrace();
}

Проблема все еще там, но первые байты изменились, теперь я получаю:

[x] Received '□�□□□□□□□w�{"one":"two","three":"four"}'

1 Ответ

0 голосов
/ 27 февраля 2019

Пожалуйста, смотрите этот ответ , который разъясняет, как кодировать полезную нагрузку и избегать этих дополнительных байтов:

, если клиент AMQP 1.0 отправляет сообщение клиенту 0-9-1 и кодируетее полезная нагрузка в двоичном виде в «разделе данных» (т. е. не в разделе amqp-sequence, не в разделе amqp-value) клиент 0-9-1 должен получить полную полезную нагрузку без каких-либо дополнительных байтов


ПРИМЕЧАНИЕ: команда RabbitMQ контролирует список рассылки rabbitmq-users и только иногда отвечает на вопросы по StackOverflow.

...