前言:本文是总结整理出来的,若有错误的地方请指出,记得每天微笑。

直连模式(direct)

  • 什么是直连模式

    任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。

    1. 需要一个 “RouteKey” 就是要发送队列的名字
    2. 不需要绑定任何一个queue
    3. 使用的是rabbitMQ自带的Exchange
    4. 如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。
  • 使用场景

    我们需要将消息发给唯一一个节点时使用这种模式。

  • 创建队列

    Durability: 是否做持久化
    Auto delete: 是否自动删除

  • direct

  1. 创建springboot项目进行测试
        <!--所需要的包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
  1. 配置文件
spring:
  rabbitmq:
    host: localhost
  1. 编写listener 消费者
@Component
@RabbitListener(queues = "directqueue") //填写刚刚设置的队列
public class DirectListener {

    @RabbitHandler
    public void showMsg(String msg) {

        System.out.println(msg);

    }
}

  1. 编写生产者测试
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void contextLoads() {
        rabbitTemplate.convertAndSend("directqueue", "我是direct模式");
    }

}

控制台输出

分列模式(Fanout)

  • 什么是分列模式

    任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
  1. 不需要 “RouteKey”
  2. 这个模式需要将Exchange与Queue进行绑定,一个Exchange可以与多个queue绑定
  3. 如果交换器没有与任何一个queue绑定,消息就会背抛弃
  • 使用场景
    当我们需要将消息一次发给多个队列时,需要使用这种模式。
  • Fanout
  1. 新建交换器
  2. 创建2个队列(用于绑定交换器)
  3. 将fanouta和fanoutb绑定到交换器(fanoutexchange)
  4. 绑定成功
  5. 编写生产者
    监听fanouta消息

@RabbitListener(queues = "fanouta") //监听fanouta
@Component
public class FanoutAListener {

    @RabbitHandler
    public void getMsg(String msg) {
        System.out.println("fanouta接收到的:"+msg);
    }
}

监听fanoutb消息

@RabbitListener(queues = "fanoutb") // 监听fanoutb
@Component
public class FanoutBListener {

    @RabbitHandler
    public void getMsg(String msg) {

        System.out.println(" fanouta接收到的:"+msg);
    }

}

  1. 编写消费者
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void fanout() {
        rabbitTemplate.convertAndSend("fanoutexchange", "","我是fanout模式");
    }
}

  1. 输出

    发送到交换器,交换器会发送到fanouta与fanoutb队列中

主题模式(Topic)

  • 什么是主题模式

    任何发送到Topic Exchange的消息都会被转发到所有关心RouteKey中指定话题的Queue 上
  1. 这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有一个“标题”(RouteKey),Exchange会将消息转发到所有关注主题能与RouteKey模糊匹配的队列。
  2. 这种模式需要RouteKey,也许要提前绑定Exchange与Queue。
  3. 在进行绑定时,要提供一个该队列关心的主题,如“#.log.#”表示该队列关心所有涉及 log的消息(一个RouteKey为”MQ.log.error”的消息会被转发到该队列)。
  4. “#”表示0个或若干个关键字,“”表示一个关键字。如“log.”能与“log.warn”匹配,无法与“log.warn.timeout”匹配;但是“log.#”能与上述两者匹配。
  5. 同样,如果Exchange没有发现能够与RouteKey匹配的Queue,则会抛弃此消息
  • Topic
  1. 新建交换器
  2. 创建队列
  3. 与交换器绑定
  4. 编写生产者
    监听topica
@RabbitListener(queues = "topica")
@Component
public class Topica {

    @RabbitHandler
    public void showMsg(String msg) {

        System.out.println("topica接收到的:"+msg);

    }
}

监听topicb

@RabbitListener(queues = "topicb")
@Component
public class Topicb {

    @RabbitHandler
    public void showMsg(String msg) {

        System.out.println("topicb接收到的:"+msg);

    }
}

监听topicc

@RabbitListener(queues = "topicc")
@Component
public class Topicc {

    @RabbitHandler
    public void showMsg(String msg) {

        System.out.println("topicc接收到的:"+msg);

    }
}

  1. 编写消费者
  • 测试#.change

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {


    @Autowired
    private RabbitTemplate rabbitTemplate;

       @Test
    public void topica() {
        rabbitTemplate.convertAndSend("topicexchange", "a.change","我是topic模式");
    }
}
  • 输出结果
  • 测试ex.#
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class MqApplicationTests {


    @Autowired
    private RabbitTemplate rabbitTemplate;

        @Test
    public void topicb() {
        rabbitTemplate.convertAndSend("topicexchange", "ex.a","我是topic模式");
    }


}
  • 输出结构
  • 我们测试下ex.change
  @Test
    public void topicc  () {
        rabbitTemplate.convertAndSend("topicexchange", "ex.change","我是topic模式");
    }


  • 输出结果

    # 匹配多个或一个
    * 匹配一个(用的较少)