RabbitMQ教程

本文介绍了RabbitMQ的安装、工作模型,详细讲解了Direct、Topic、Fanout三种交换机的用法,并通过实例展示了如何在Spring Boot应用中集成RabbitMQ,包括设置依赖、配置连接信息、定义交换机、队列和绑定,以及创建生产者和消费者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.安装

RabbitMQ使用Erlang语言编写,运行时需要依赖Erlang语言环境,安装RrabbitMQ前需要先安装Erlang,且两者的版本要配套。

Windows系统上安装成功后,只需在开始菜单点击RabbitMQ Service -start便可以启动RabbitMQ服务,RabbitMQ提供了web页面对其服务进行可视化管理,要使用web界面需要在RabbitMQ的安装目录下执行如下命令

rabbitmq-plugins enable rabbitmq_management

二.RabbitMQ工作模型

模型中的相关概念解释

Producer消息生产者。主要将消息投递到对应的Exchange上面。一般是独立的程序。
Routing Key路由关键字。Exchange根据Routing Key进行消息投递
Exchange消息交换机。指定消息按照什么规则路由到哪个队列Queue。
Queue消息队列。消息的载体。每条消息都会被投送到一个或多个队列中。
Broker即RabbitMQ的实体服务器。提供一种传输服务,维护一条从生产者到消费者的传输线路,保证消息数据能按照指定的方式传输。
Virtual host虚拟主机。一个Broker可以有多个虚拟主机,用作不同用户的权限分离。一个虚拟主机持有
一组Exchange、Queue和Binding。
Binding绑定。作用就是将Exchange和Queue按照某种路由规则绑定起来。
Binding keyExchange和Queue之间的绑定规则
ConnectionProducer 和 Consumer 与Broker之间的TCP长连接。
Channel消息通道,也称信道。在客户端的每个连接里可以建立多个Channel,每个Channel代表一
个会话任务。在RabbitMQ Java Client API中,channel上定义了大量的编程接口。

 

 

 

 

 

 

 

 

 

 

 

 

三.常用交换机介绍

交换机主要是接收消息并且转发到与其绑定的队列,常用的交换机有类型有:Direct、Topic、Fanout

Direct Excange

直连交换机,其路由规则是:routing key与binding key完全匹配时,消息才会被投递到绑定的队列中。

Topic Exchange

主题交换机,其路由规则是通配符模糊匹配,若routing key与binding key匹配成功,则消息会被投递到绑定的队列中。binding key通常为包含通配符的字符串,如 gjw.test.*,其中*表示任意一个单词,该binding key可以匹配诸如gjw.test.abcd、gjw.test.xxx、gjw.test.msg等格式的routing key;除了*通配符外,还有#通配符,它表示零个或多个单词,比如gjw.test.#可以匹配gjw.test.abc、gjw.test.abc.def、gjw.test.aaa.bbb.ccc等格式的routing key。

Fanout Exchange

广播交换机,广播类型的交换机与队列绑定时不需要指定binding key,当发送消息到广播交换机时也不需要指定routing key,它会将消息投递到所有与之绑定的队列中。

四.Spring Boot集成RabbitMQ

1.引入消息队列的maven依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2.在配置文件中加入RabbitMQ的连接信息

#rabbitmq连接信息配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

3.配置交换机、队列、以及二者的绑定关系

@Configuration
public class Configure {
    //配置一个直连交换机,交换机名为gjwDirectExchange
    @Bean
    public DirectExchange DirectExchange(){
        return new DirectExchange("gjwDirectExchange");
    }

    //配置一个队列,队列名为testQueue1
    @Bean
    public Queue Queue1(){
        return new Queue("testQueue1");
    }

    //将交换机gjwDirectExchange与队列testQueue1绑定,binding key为test.direct.key
    @Bean
    public Binding Binding(@Qualifier("Queue1") Queue queue, @Qualifier("DirectExchange") DirectExchange directExchange){
        return BindingBuilder.bind(queue).to(directExchange).with("test.direct.key");
    }

}

4.创建消息生产者与消费者

/**
 * 消息生产者
 */
@Component
public class Producer {
    @Autowired
    private RabbitTemplate template;

    public void sendMessage(){
        //向gjwDirectExchange交换机发送消息,routing key为test.direct.key
        template.convertAndSend("gjwDirectExchange","test.direct.key","hello direct exchange");
    }

}
/**
 * 消息消费者
 */
@Component
//配置消费者监听testQueue1队列中的消息
@RabbitListener(queues = "testQueue1")
public class Consumer {
    @RabbitHandler
    public void msgReceive(String msg){
        System.out.println("receive msg : "+msg);
    }
}

5.测试消费发送

@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {

    @Autowired
    private Producer producer;

    @Test
    public void sendMessage() throws Exception {
        producer.sendMessage();
    }

}

运行结果

由于发送消息时的routing key与binding key是完全一致的,因此消息会被转发到testQueue1队列中,监听此队列的消费者便可以收到消息。

6.主题交换机demo

@Configuration
public class Configure {
    //配置一个主题交换机,交换机名为gjwTopicExchange
    @Bean
    public TopicExchange TopicExchange(){
        return new TopicExchange("gjwTopExchange");
    }

    //配置一个队列,队列名为testQueue1
    @Bean
    public Queue Queue1(){
        return new Queue("testQueue1");
    }

    //将交换机gjwTopicExchange与队列testQueue1绑定,binding key为test.topic.#
    @Bean
    public Binding Binding(@Qualifier("Queue1") Queue queue, @Qualifier("TopicExchange") TopicExchange topicExchange){
        return BindingBuilder.bind(queue).to(topicExchange).with("test.topic.#");
    }

}
/**
 * 消息生产者
 */
@Component
public class Producer {
    @Autowired
    private RabbitTemplate template;

    public void sendMessage(String routingKey){
        //向gjwTopicExchange交换机发送消息
        template.convertAndSend("gjwTopicExchange",routingKey,"hello topic exchange");
    }

}
//测试消息发送
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {

    @Autowired
    private Producer producer;

    @Test
    public void sendMessage() throws Exception {
        producer.sendMessage("test.topic.abc");
        producer.sendMessage("test.topic.def.ghi");
    }

}

运行结果

可以看到,使用两个不同的routing key发送消息,消费者都可以收到,这是因为test.topic.abc和test.topic.def.ghi这两个routing key都可以模糊匹配到test.topic.#

7.广播交换机demo

@Configuration
public class Configure2 {
    //配置一个广播交换机,交换机名为gjwFanoutExchange
    @Bean
    public FanoutExchange FanoutExchange(){
        return new FanoutExchange("gjwFanoutExchange");
    }

    //配置一个队列,队列名为testQueue1
    @Bean
    public Queue Queue1(){
        return new Queue("testQueue1");
    }

    //配置一个队列,队列名为testQueue2
    @Bean
    public Queue Queue2(){
        return new Queue("testQueue2");
    }

    //将交换机gjwFanoutExchange与队列testQueue1绑定,不需要指定binding key
    @Bean
    public Binding Binding1(@Qualifier("Queue1") Queue queue, @Qualifier("FanoutExchange") FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

    //将交换机gjwFanoutExchange与队列testQueue2绑定,不需要指定binding key
    @Bean
    public Binding Binding2(@Qualifier("Queue2") Queue queue, @Qualifier("FanoutExchange") FanoutExchange fanoutExchange){
        return BindingBuilder.bind(queue).to(fanoutExchange);
    }

}
/**
 * 消息生产者
 */
@Component
public class Producer {
    @Autowired
    private RabbitTemplate template;

    public void sendMessage(){
        //向gjwFanoutExchange交换机发送消息,不指定routing key
        template.convertAndSend("gjwFanoutExchange","","hello fanout exchange");
    }

}
/**
 * 消息消费者
 */
@Component
//配置消费者1监听testQueue1队列中的消息
@RabbitListener(queues = "testQueue1")
public class Consumer1 {
    @RabbitHandler
    public void msgReceive(String msg){
        System.out.println("consumer1 receive msg : "+msg);
    }
}
/**
 * 消息消费者
 */
@Component
//配置消费者2监听testQueue2队列中的消息
@RabbitListener(queues = "testQueue2")
public class Consumer2 {
    @RabbitHandler
    public void msgReceive(String msg){
        System.out.println("consumer2 receive msg : "+msg);
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTest {

    @Autowired
    private Producer producer;

    @Test
    public void sendMessage() throws Exception {
        producer.sendMessage();
    }

}

运行结果

可以看到,消息被投递到两个队列中,分别被两个消费者消费。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值