问题背景

感觉rabbit的使用非常混乱,有很多的包,乱七八糟,各家封装的都有,有时候能成功有的时候不能成功。
而且很多的包名称还完全一样(当然,namesapce不同),导致出现一些奇怪的问题。
而且跟spring bootspring-boot-starter-web之类的还可能有一定的关系,都比较凌乱。
经过艰难的尝试,大概终于理清楚了。
这次记录一下。

概述

目前我亲测成功过的,有三种方式。

  1. channel.basicPublish() 方式
  2. rabbitTemplate.send()方式
  3. amqpTemplate.send()方式

实际上,经过在源码里跳来跳去,大概可以得出结论就是 2 和 3 都是对 1 的进一步封装。
其中方法1最简单,也最基础,最好理解。
但就是接收消息有点不太优雅,除非是两个控制台项目互相收发弄着玩。
参考地址:https://help.aliyun.com/document_detail/106230.html

后面两种就是项目中见的比较多的,尤其是springboot项目。
经过模式,梳理出 的 2和3 的关系:

就像是rabbitmq是一个开源产品,人人都可以用。
A公司封装了一套,
包名为:com.rabbitmq.client.***
里面有:RabbitTemplatecom.rabbitmq.client.ConnectionFactory等类。

B公司封装了一套,
包名为:org.springframework.amqp.rabbit.***.***
里面有:AmqpTemplateorg.springframework.amqp.rabbit.connection.CachingConnectionFactory等类。

这两家公司封装的东西都可以独立实现完成收发消息的功能。
基于这点理解,各种依赖关系不再混乱,剩下的就很好办了。


示例

直接上一个demo,操作aliyun的rabbitmq。

一个springboot项目。
大致结构如下图:
在这里插入图片描述
实现的效果:

  1. 可以使用A公司封装的内容,收发消息。
  2. 可以使用B公司封装的内容,收发消息。

结果: 成功实现。

具体实现

注:rabbitmq上的exchange、queue自己建,绑定关系自己处理。
当然,程序也可以实现,只是程序中没这么做。

依赖

此springboot项目的依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>aliyun-rabbitmq-springboot-demo</artifactId>
    <version>1.0-SNAPSHOT</version>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.9.RELEASE</version>
        </dependency>

        <!--  来源       https://help.aliyun.com/document_detail/106230.html-->
<!--        <dependency>-->
<!--            <groupId>com.rabbitmq</groupId>-->
<!--            <artifactId>amqp-client</artifactId>-->
<!--            <version>5.5.0</version> &lt;!&ndash; 支持开源所有版本 &ndash;&gt;-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.alibaba.mq-amqp</groupId>
            <artifactId>mq-amqp-client</artifactId>
            <version>1.0.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>2.1.11.RELEASE</version>
        </dependency>

    </dependencies>
</project>

发消息

package com.xj.rabbitmq.demo.controller;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author zss
 * @date 2022/4/26 10:56
 * @Email:451682479@qq.com
 */
@RequestMapping("/test")
@RestController
public class TestController {


    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Autowired
    private AmqpTemplate amqpTemplate;

    @GetMapping("/rabbitSend")
    public String rabbitSend() {

        for (int i = 0; i < 10; i++) {

            String a = "rabbit 消息发送Body" + i;
            byte[] bytes = a.getBytes();

            MessageProperties messageProperties = new MessageProperties();
            Message message = new Message(bytes, messageProperties);

            rabbitTemplate.send("test-direct-exchange", "aaaa", message);

            System.out.println(a);
        }
        return "";
    }


    @GetMapping("/amqpSend")
    public String amqpSend() {

        for (int i = 0; i < 10; i++) {

            String a = "amqpTemplate2 消息发送Body" + i;
            amqpTemplate.convertAndSend("test-direct-exchange", "bbbb", a);

            System.out.println(a);
        }
        return "";
    }


}

收消息

接收消息,怎么发就怎么接。
发Message,就用Message参数类型接。
发Object 就用Object类型的参数接。
这是我反复实验得出的不不易报错的结论。

Mq1Listener

package com.xj.rabbitmq.demo.listener.testqueue1;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author zss
 * @date 2022/4/26 15:51
 * @Email:451682479@qq.com
 */
@Component
public class Mq1Listener {

    /**
     * amqp方式 listener
     * @param msg
     */
    @RabbitListener(queues = "test-queue1")
    public void handleMessage(Message msg) {

        byte[] body = msg.getBody();
        String s = new String(body);
        System.out.println("11111 listener 收到消息 " + s);
    }
}

Mq2Listener

package com.xj.rabbitmq.demo.listener.testqueue2;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author zss
 * @date 2022/4/26 11:38
 * @Email:451682479@qq.com
 */
@Component
public class Mq2Listener {

    /**
     * rabbit 方式 listener
     */
    @RabbitListener(queues = "test-queue2")
    public void handleMessage(String msg) {
        System.out.println("22222 listener 收到消息4 " + msg);
    }
}

项目地址

springboot集成rabbitmq的代码示例(账号密码等已处理,自行填充自己的,使用的是aliyun的rabbitmq服务)

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐