RabbitTemplate发送MQ消息丢失MessageId

背景
在Java项目中,我们使用RabbitMQ发送消息的时候,一般采用RabbitTemplate,比如采用convertAndSend方法发送一个简单的字符串消息,这个时候我们会发现,消费者的MessageId是null,也就是MessageId没有被赋值,这对于我们想做幂等性判断的场景下,无法使用。那原因是什么,如何解决的呢?

首先我们看下convertAndSend方法做了哪些事情

public void convertAndSend(String routingKey, Object object) {
    this.convertAndSend(this.exchange, routingKey, object, (CorrelationData)null);
}

public void convertAndSend(String exchange, String routingKey, Object object, @Nullable CorrelationData correlationData) {
    this.send(exchange, routingKey, this.convertMessageIfNecessary(object), correlationData);
}

protected Message convertMessageIfNecessary(Object object) {
    return object instanceof Message ? (Message)object : this.getRequiredMessageConverter().toMessage(object, new MessageProperties());
}

我们会看到,消息发送,最终要转换为Message对象,也就是调用convertMessageIfNecessary方法,而这个方法需要获取Converter,并且调用toMessage方法转换为Message对象。

private MessageConverter messageConverter = new SimpleMessageConverter();
private MessageConverter getRequiredMessageConverter() throws IllegalStateException {
    return this.getMessageConverter();
}
public MessageConverter getMessageConverter() {
    return this.messageConverter;
}

我们发现获取的Converter最终是SimpleMessageConverter,而父类是AbstractMessageConverter,具体代码如下:

public abstract class AbstractMessageConverter implements MessageConverter {
    private boolean createMessageIds = false;
    public void setCreateMessageIds(boolean createMessageIds) {
        this.createMessageIds = createMessageIds;
    }

    public final Message toMessage(Object object, @Nullable MessageProperties messagePropertiesArg, @Nullable Type genericType) throws MessageConversionException {
        MessageProperties messageProperties = messagePropertiesArg;
        if (messageProperties == null) {
            messageProperties = new MessageProperties();
        }

        Message message = this.createMessage(object, messageProperties, genericType);
        messageProperties = message.getMessageProperties();
        if (this.createMessageIds && messageProperties.getMessageId() == null) {
            messageProperties.setMessageId(UUID.randomUUID().toString());
        }

        return message;
    }
}

我们发现setMessageId有个条件createMessageIds,默认是false,所以只需要解决这个就可以了,比如在获取RabbitTemplate的时候,设置为true

 RabbitTemplate rabbitTemplate = new RabbitTemplate();
((AbstractMessageConverter) rabbitTemplate.getMessageConverter()).setCreateMessageIds(true);
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容