Spring amqp和correlatinId

时间:2017-09-20 07:50:21

标签: rabbitmq spring-amqp spring-rabbitmq

我对Spring AMQP和AMQP消息的correlationId有些怀疑。 我有一个带有两个队列的项目(“queue.A”和“queue.B”),每个队列都有一个MessageListener:

public class ServerHandlerQueueA implements MessageListener {

    @Override
    public void onMessage(Message msg)


public class ServerHandlerQueueB implements MessageListener {

    @Override
    public void onMessage(Message msg)

在某些情况下,当我在“queue.A”中收到消息时,我必须将其重定向到“queue.B”:

rabbitTemplate.convertAndSend(routingkey, msg, new MessagePostProcessor() 
    { …});

在所有情况下,我都会使用以下内容将响应发送给客户端:

String routingkey = msg.getMessageProperties().getReplyTo();
rabbitTemplate.convertAndSend(routingkey, respuesta, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message msg) throws AmqpException 
{….}
});

如果我在客户端使用Spring AMQP,这是正常的:

Object _response = getRabbitOperations().convertSendAndReceive(requestExchange, routingKeyManagement, msg,
new MessagePostProcessor() 
        {
            public Message postProcessMessage(Message message) throws AmqpException 
            {….}
        });

但如果我使用java客户端(在客户端):

RpcClient _rpcClient = new RpcClient(channel, exchangeName, routingKey);
        Response _response = _rpcClient.doCall(new AMQP.BasicProperties.Builder()
                   .contentType("application/json")
                   .deliveryMode(2)
                   .priority(1)
                   .userId("myUser")
                   .appId("MyApp")
                   .replyTo(replyQueueName)
                   .correlationId(corrId)
                   .type("NewOrder")
                   .build(), 
                   messageBodyBytes);

我总是在:

中得到NullPointerException
com.rabbitmq.client.RpcClient$1.handleDelivery(RpcClient.java:195)

我认为这是因为correlationId治疗。当我使用Spring AMQP发送消息时,我可以在使用者中看到“spring_listener_return_correlation”和“spring_request_return_correlation”标头,但“correlationId”属性始终为null。 如何使它与纯Java客户端和Spring AMQP兼容?我做错了什么? 谢谢!

------编辑---------- 我升级到Spring AMQP 1.7.4版本。 我发这样的信息:

Object respuesta = getRabbitOperations().convertSendAndReceive(requestExchange, routingKey, _object, 
            new MessagePostProcessor() 
            {
                public Message postProcessMessage(Message message) throws AmqpException 
                {
                    message.getMessageProperties().setUserId(“myUser”);
                    message.getMessageProperties().setType(“myType”);
                    message.getMessageProperties().setAppId("myApp");
                    message.getMessageProperties().setMessageId(counter.incrementAndGet() + "-myType");
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                    message.getMessageProperties().setRedelivered(false);

                    return message;
                }
            });

在服务器上我有:

@Override
    public void onMessage(Message msg) 
    {
        MessageProperties mp = msg.getMessageProperties();
Gson __gson = new Gson();
                    String _stringMP = __gson.toJson(mp);
                    System.out.println("MessageProperties:\n" + _stringMP);
}

我认为问题是我总是得到correlationId null:

{"headers":{"spring_listener_return_correlation":"49bd0a84-9abb-4719-b8a7-8668a4a77f32","spring_request_return_correlation":"32","__TypeId__":"MyType"},"messageId":"32-MyType","appId":"myApp","type":"MyType","replyTo":"amq.rabbitmq.reply-to.g2dkABByYWJiaXRATkRFUy1QQzAyAAAsMwAAAAgD.ia4+GgHgoeBnajbHxOgW+w\u003d\u003d","contentType":"application/json","contentEncoding":"UTF-8","contentLength":0,"contentLengthSet":false,"priority":0,"redelivered":false,"receivedExchange":"requestExchange","receivedRoutingKey":"inquiry","receivedUserId":"myUser",
"deliveryTag":5,"deliveryTagSet":true,"messageCount":0,"consumerTag":"amq.ctag-4H_P9CbWYZMML-QsmyaQYQ","consumerQueue":"inquiryQueue","receivedDeliveryMode":"NON_PERSISTENT"}

如果我使用Java Client,我可以看到correlationId:

{"headers":{},"appId":"XBID","type":"MyOrders","correlationId":[49], ….

------------ EDIT 2 ------------------------------ -
我尝试过:

getRabbitOperations().convertAndSend(requestExchange, routingKeyInquiry, 
                _object, 
                new MessagePostProcessor() 
                {
                    public Message postProcessMessage(Message message) throws AmqpException 
                    {
                        message.getMessageProperties().setUserId(“myUser”);
                        message.getMessageProperties().setType(“myType”);
                        message.getMessageProperties().setAppId("myApp");
                        message.getMessageProperties().setMessageId(counter.incrementAndGet() + "-myType");
                        message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                        message.getMessageProperties().setRedelivered(false);
                        message.getMessageProperties().setCorrelationIdString(UUID.randomUUID().toString());
                        return message;
                    }
                });

但" correlationId"在服务器端始终为空。

1 个答案:

答案 0 :(得分:1)

您使用的是哪个版本?

返回相关标头与correlationId无关;它们用于关联返回的(强制)请求和回复。

只要您将correlationIdreplyTo邮件从queue.A邮件复制到queue.B邮件,就可以正常运行。

如果您无法解决问题,请在所有3台服务器上发布调试日志。

修改

这对我来说很好......

@SpringBootApplication
public class So46316261Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(So46316261Application.class, args).close();
    }

    @Autowired
    private RabbitTemplate template;

    @Override
    public void run(String... arg0) throws Exception {
        Object reply = this.template.convertSendAndReceive("queue.A", "foo");
        System.out.println(reply);
        Connection conn = this.template.getConnectionFactory().createConnection();
        Channel channel = conn.createChannel(false);
        RpcClient client = new RpcClient(channel, "", "queue.A");
        Response response = client.doCall(new AMQP.BasicProperties.Builder()
                .contentType("text/plain")
                .deliveryMode(2)
                .priority(1)
                .userId("guest")
                .appId("MyApp")
                .replyTo("amq.rabbitmq.reply-to")
                .correlationId("bar")
                .type("NewOrder")
                .build(),
                "foo".getBytes());
        System.out.println(new String(response.getBody()));
        channel.close();
        conn.close();
    }

    @Bean
    public Queue queueA() {
        return new Queue("queue.A");
    }

    @Bean
    public Queue queueB() {
        return new Queue("queue.B");
    }

    @RabbitListener(queues = "queue.A")
    public void listen(Message in) {
        System.out.println(in);
        this.template.send("queue.B", in);
    }

    @RabbitListener(queues = "queue.B")
    public String listenB(Message in) {
        System.out.println(in);
        return "FOO";
    }

}


(Body:'foo' MessageProperties [headers={}, correlationId=1, replyTo=amq.rabbitmq.reply-to.g2dkABByYWJiaXRAbG9jYWxob3N0AAACyAAAAAAB.hp0xZxgVpXcuj9+5QkcOOw==, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, priority=0, redelivered=false, receivedExchange=, receivedRoutingKey=queue.B, deliveryTag=1, consumerTag=amq.ctag-oanHvT3YyUb_Lajl0gpZSQ, consumerQueue=queue.B])
FOO
(Body:'foo' MessageProperties [headers={}, appId=MyApp, type=NewOrder, correlationId=1, replyTo=amq.rabbitmq.reply-to.g2dkABByYWJiaXRAbG9jYWxob3N0AAACzAAAAAAB.okm02YXf0s0HdqZynVIn2w==, contentType=text/plain, contentLength=0, priority=1, redelivered=false, receivedExchange=, receivedRoutingKey=queue.B, deliveryTag=2, consumerTag=amq.ctag-oanHvT3YyUb_Lajl0gpZSQ, consumerQueue=queue.B])
FOO