Rabbit为AMQP 1.0消息节省了额外的字节

时间:2019-02-12 11:41:52

标签: rabbitmq amqp

我有一个环境,其中某些AMQP 1.0和某些AMQP 0.9.1客户端需要对RabbitMQ队列进行读写操作。我启用了AMQP 1.0兔子插件,并且可以正常工作,但是每条AMQP 1.0消息的正文中都有多余的字节。

我正在使用rhea(打字稿)通过AMQP1.0发送消息:

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我没有发送。

我尝试使用官方RabbitMQ库(使用AMQP 0.9.1)设置Java客户端,以查看是否将这些额外的字节发送给了客户端:

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 :(得分:0)

请参阅this response,其中阐明了如何编码有效载荷并避免这些额外的字节:

  

如果AMQP 1.0客户端向0-9-1客户端发送消息,并将其有效载荷编码为“数据段”中的二进制(即,不在amqp序列段中,不在amqp值段中),则为0-9-1客户端将获得完整的有效载荷,而没有任何额外的字节


注意: RabbitMQ团队监视rabbitmq-users mailing list,并且有时仅在StackOverflow上回答问题。