springboot中rabbitmq集成——多项目

本文介绍在SpringBoot中如何实现RabbitMQ的多项目集成,通过实例展示了消息生产者和消费者之间的交互。在不同项目间传递字符串没有问题,但当尝试传递自定义对象时遇到问题,由于类路径不一致导致消费失败。解决方案包括让对象类包路径一致或转换为JSON字符串。作者分享了自己的实践和思考。

这里以两个项目为例,一个消息的生产者,一个消息的消费者,接着上篇单项目的讲。

目录结构:
这里写图片描述

rabbitmq作为消息生产者,发送消息。rabbitmqreceiver消息的接收者,消费消息。
发送字符串的时候在两个项目之间是没问题的,大家可以自己测试。

发送端代码:

    public void run(String... args) throws Exception {

        User user=new User();
        for (int i = 0; i < 10; i++) {
            user.setUserName("庞坤");
            user.setAge(i);
            user.setAddress("上海市徐汇区漕河泾开发区");

            rabbitTemplate.convertAndSend("my-rabbitmq", user);
            System.out.println("消息发送了"+(i+1)+"次");
        }
        System.out.println("发送结束");


    }

接收端的代码(两边一样):

    @RabbitListener(queues="my-rabbitmq")
    public void receive(User user){
        System.out.println("我收到的消息是:"+user);
        System.out.println("Address:"+user.getAddress());
        System.out.println("UserName:"+user.getUserName());
        System.out.println("Age:"+user.getAge());
    }

rabbitmq的log:

消息发送了1次
消息发送了2次
消息发送了3次
消息发送了4次
消息发送了5次
消息发送了6次
消息发送了7次
消息发送了8次
消息发送了9次
消息发送了10次
发送结束

我收到的消息是:com.rhett.rabbitmq.User@32356124
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:1
我收到的消息是:com.rhett.rabbitmq.User@49630975
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:3
我收到的消息是:com.rhett.rabbitmq.User@325be57c
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:5
我收到的消息是:com.rhett.rabbitmq.User@2ad5fd18
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:7
我收到的消息是:com.rhett.rabbitmq.User@33f08527
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:8

从这里可以看到消息的发送和消费是异步的,消息生成后不会等待被消费使用。所以大家可以充分利用这点来使用mq。

rabbitmqreceive的log如下图:
这里写图片描述
这里是部份错误日志,没消费一条消息都会报错。

从上面的log可以看出rabbitmqreceive的User对象无法接收rabbitmq传过来的User对象,而是在找寻rabbitmq下的user。

等下再说解决方案,这里先看HashMap的传送。

发送端代码:

    public void run(String... args) throws Exception {

        HashMap<String,Object> hm=new HashMap<String,Object>();
        for (int i = 0; i < 10; i++) {
            hm.put("userName", "庞坤");
            hm.put("age", i+1);
            hm.put("address", "上海市徐汇区漕河泾开发区");

            rabbitTemplate.convertAndSend("my-rabbitmq", hm);
            System.out.println("消息发送了"+(i+1)+"次");
        }
        System.out.println("发送结束");

    }

接收端的代码(两边一样):

    @RabbitListener(queues="my-rabbitmq")
    public void receive(HashMap<String,Object> hm){
        System.out.println("我收到的消息是:"+hm);

    }

rabbitmq的log:

消息发送了1次
消息发送了2次
消息发送了3次
消息发送了4次
消息发送了5次
消息发送了6次
消息发送了7次
消息发送了8次
消息发送了9次
消息发送了10次
发送结束
2017-04-08 22:15:07.014  INFO 651 --- [           main] com.rhett.rabbitmq.RabbitmqApplication   : Started RabbitmqApplication in 5.118 seconds (JVM running for 5.587)
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=2}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=3}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=5}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=7}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=9}

rabbitmqreceive的log:

我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=1}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=4}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=6}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=8}
我收到的消息是:{address=上海市徐汇区漕河泾开发区, userName=庞坤, age=10}

此时rabbitmqreceive中的接收方法是可以正常执行的,传送String字符串的时候也是ok的。

现在再来看传送User对象在同项目中成功,在其他项目中失败的原因。
这里写图片描述
还是这张图,其中消息队列中的user对象明确指定,应用的是com.rhett.rabbitmq.user,虽然rabbitmqreceive中定义了同样的User类,但是却无法接收队列中的数据。所以,接收的对象一定要是com.rhett.rabbitmq.user这里的类生成的对象。(具体其它原因大家自己考虑,这里是我个人的观点,只是从表面上分析)

从这点入手,1、另写一个pojo专门用来存放产生消息的对象;2、将rabbitmq整个项目引入到rabbitmqreceive中。
这里我采用第二种方式,pom中的代码如下:

    <!--引入rabbitmq -->
    <dependency>
        <groupId>com.rhett</groupId>
        <artifactId>rabbitmq</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

继续使用user作为消息的传送对象,查看rabbitmqreceive中的log:

我收到的消息是:com.rhett.rabbitmq.User@6a45940b
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:0
我收到的消息是:com.rhett.rabbitmq.User@4f4ee63d
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:3
我收到的消息是:com.rhett.rabbitmq.User@21940478
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:4
我收到的消息是:com.rhett.rabbitmq.User@5e2659c8
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:6
我收到的消息是:com.rhett.rabbitmq.User@18857bcb
Address:上海市徐汇区漕河泾开发区
UserName:庞坤
Age:8

此时可以看出在rabbitmqreceive中也可以正常的消费user对象的消息了。
除了引入同一个类包来实现对象的消费外,还可以用Json来实现,发送的时候把user对象转为Json字符串,接收的时候用字符串来接收,然后转成相应的对象,不需要引用com.rhett.rabbitmq.user。这种方法我试过,是可以的,以后把代码补上来。

以下是补充的一个方法:
今天早上起来后想到一个新方法,就是两个项目中需要传递的对象包的目录级别命名一致,问过一些人都说没问题,下面给出具体实现:
这里写图片描述

现在user类的路径在两个项目中都是com.rhett.user。所以解析的都时候对象的映射都是一样的,完全可以正常在两个项目中使用。这时候两个项目的启动类都要调换位置,因为spring boot的启动类是要放到最外层的,要不然没发识别上一层的类注解。

如果需要使用这个类的项目是多个,还想要使用类直接传递,最好还是把类作为一个pojo来引入比较好。

由于本人刚接触mq,水平有限,暂时还不能从本质上来解决问题,如果哪位大神看到,还请留下建言。如果各位看到有不对的地方还请指正,感谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值