SpringBoot引入RabbitMQ(二):關於無法消費消息的問題


前文:SpringBoot引入RabbitMQ(一):引入進SpringBoot中

在前文中,就出現過一次無法發送消息的問題

原因:SpringBoot在啟動時,就會自動生成配置好的Queue、Exchange、Key等等,但是如果初次啟動時只有生產者或者消費者的情況下,並不會建立他們,所以發送消息失敗。

解決:生產者、消費者都配置好之后,逐一啟動即可自動生成,然后就可以正常發送消息了

 

現在生產者、消費者分開放在兩個Demo中,再模擬一下收發消息

生產者:

原項目做生產者,具體搭建方法參考上文

OutSendMessageDTO

package com.zyuan.boot.rabbitmq.message.dto;

@Data
public class OutSendMessageDTO implements Serializable { private static final long serialVersionUID = 1L; private Long id; private String messageInfo; }

MqConstant

public class MqConstant {public static final String OUT_SEND_MESSAGE_QUEUE = "outSendMessageQueue";
    public static final String OUT_SEND_MESSAGE_EXCHANGE = "outSendMessageExchange";
    public static final String OUT_SEND_MESSAGE_KEY = "outSendMessageKey";
}

OutSendMessageProducer

import com.zyuan.boot.rabbitmq.message.constant.MqConstant;
import com.zyuan.boot.rabbitmq.message.dto.OutSendMessageDTO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class OutSendMessageProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendOutMessage(OutSendMessageDTO outSendMessageDTO) {
        System.out.println("外發了一條消息");
        try {
            rabbitTemplate.convertAndSend(MqConstant.OUT_SEND_MESSAGE_EXCHANGE, MqConstant.OUT_SEND_MESSAGE_KEY, outSendMessageDTO);
            System.out.println("外發消息成功");
        } catch (Exception e) {
            System.out.println("外發消息失敗");
            e.printStackTrace();
        }
    }

}

測試類:

@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitMqTest {
    @Autowired
    private OutSendMessageProducer outSendMessageProducer;
@Test public void sendOutMessage() { OutSendMessageDTO outSendMessageDTO = new OutSendMessageDTO(); outSendMessageDTO.setId(9999999L); outSendMessageDTO.setMessageInfo("這是外發的消息"); outSendMessageProducer.sendOutMessage(outSendMessageDTO); } }

 

消費者:

將OutSendMessageDTO、MqConstant復制過來

OutSendMessageConsumer

import com.rabbitmq.client.Channel;
import com.zyuan.boot.rabbitmqconsum.message.constant.MqConstant;
import com.zyuan.boot.rabbitmqconsum.message.dto.OutSendMessageDTO;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class OutSendMessageConsumer {

    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue(value = MqConstant.OUT_SEND_MESSAGE_QUEUE),
                            exchange = @Exchange(value = MqConstant.OUT_SEND_MESSAGE_EXCHANGE),
                            key = MqConstant.OUT_SEND_MESSAGE_KEY
                    )
            }
    )
    public void consumeFirstMessage(@Payload OutSendMessageDTO outSendMessageDTO, Channel channel, Message message) {
        System.out.println("消費到了外發的信息:" + outSendMessageDTO.toString());
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

消息測試:

運行測試類,生產者開始發送消息:

發送成功

但是切到消費者項目查看控制台發現報錯了:

 往下翻發現問題點:

可以發現,明明是復制過來的DTO對象,為什么會找不到對象呢

其實在真正的項目開發時,生產者、消費者使用的對象都是同一個,假如生產者創建了這個Message對象,那么應該通過打包、消費者引入Jar包的方式來使用這個對象

所以問題點就顯而易見了:

package路徑不同,導致序列化出現差異,所以報錯

解決:

將消費者的DTO路徑改為與生產者一致

 再次進行收發消息:

成功消費了消息

 

拓展:在實際開發中,可能會配置MessageConverter,但是不同項目之間可能不同,比如生產者使用SimpleMessageConverter,消費者使用Jackson2JsonMessageConverter

那么就會報錯 Json keyword missing,這點要注意

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM