五分钟入门 RabbitMQ 🐇

112 阅读3分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

RabbitMQ 🐇

又称兔子 MQ,和兔年十分般配。兔子敏捷灵活、繁殖迅速,也祝大家兔年随机应变、财源滚滚。

MQ,message queue,指消息队列。简单来说,它就是一个消息传递的中间件,充当数据缓冲和分发的角色。

消息队列主要作用

解耦、异步、削峰。

通俗解释,

解耦:从打电话变为发短信。

异步:多个人同时给你发短信的同时,你能给多个人发短信。

削峰:一万个人同时给你发短信时,你能控制这些短信一百条、一百条的发给你。等你处理完这一百条之后,再处理下一百条。

RabbitMQ 简介

RabbitMQ 是一个实现了高级消息队列协议 (AMQP) 的开源消息队列系统。RabbitMQ 服务器是用 Erlang 语言编写的。Erlang 对于高并发和分布式非常友好。

AMQP 是一种消息传递协议,它规定了消息系统中三大组件——服务器、生产者、消费者之间的通信规范。

除此之外,RabbitMQ 还支持 AMQP 0-9-1、AMQP 1.0、STOMP、MQTT协议。并通过插件可以实现流、HTTP、WebSocket 通信。

发个兔子 🐇

安装

下载 Downloads - Erlang/OTP,配置环境变量 %ERLANG_HOME%\bin.

然后安装 RabbitMQ,安装完后进入sbin目录,运行命令:

rabbitmq-plugins enable rabbitmq_management

命令.png

如果提示你,

changes will take effect at broker restart

那么需要重启RabbitMQ,启动/停止命令:

net start RabbitMQ
net stop RabbitMQ

查看状态:

rabbitmqctl status

或者手动修改, 重启.png

上述操作完成后,可以进入 http://localhost:15672 进行验证,用户名和密码均默认为 guest,此时已经安装成功。

安装.png

快速上手

java, idea, maven

生产者

application.yml

server:
  # 项目访问的端口号
  port: 9001
spring:
  application:
    # 项目名称
    name: provider
  # 配置RabbitMQ
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

pom.xml

<parent>  
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-parent</artifactId>  
  <version>2.7.5</version>  
  <relativePath/>  
</parent>  
  
<dependencies>  
  <dependency>  
    <groupId>junit</groupId>  
    <artifactId>junit</artifactId>  
    <version>3.8.1</version>  
    <scope>test</scope>  
  </dependency>  
  <dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-amqp</artifactId>  
  </dependency>  
  <dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
  </dependency>  
</dependencies>

App.class

@SpringBootApplication  
public class App {  
    public static void main( String[] args ) {  
        SpringApplication.run(App.class,args);  
    }  
}

RabbitConfig.class

@Configuration  
public class RabbitConfig {  
    // 指定交换机名称  
    private final String EXCHANGE_NAME = "boot_topic_exchange";  
  
    // 指定队列名  
    private final String QUEUE_NAME = "boot_queue";  
  
    // 创建交换机  
    @Bean("bootExchange")  
    public Exchange getExchange() {  
        return ExchangeBuilder  
                .topicExchange(EXCHANGE_NAME)  
                .durable(true) // 是否持久化  
                .build();  
    }  
  
    // 创建队列  
    @Bean("bootQueue")  
    public Queue getMessageQueue() {  
        return new Queue(QUEUE_NAME);  
    }  
  
    // 创建交换机绑定队列  
    @Bean  
    public Binding bindingExchangeQueue(@Qualifier("bootExchange") Exchange exchange, @Qualifier("bootQueue") Queue queue) {  
        return BindingBuilder  
                .bind(queue)  
                .to(exchange)  
                .with("#.blessing.#")   // 通配符模式 要匹配的路由键 RoutingKey  
                .noargs();  
    }  
}

RabbitProvider.class

@RestController
@RequestMapping("bootRabbitMq")
public class RabbitProvider {
    // 注入 RabbitTemplate 工具类
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/send")
    public String sendMessage() {
        try {
            String messageId = String.valueOf(UUID.randomUUID());
            String messageContent = " 🐇 ";
            String sendTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            HashMap<String, Object> messageMap = new HashMap<>();
            messageMap.put("messageId", messageId);
            messageMap.put("messageContent", messageContent);
            messageMap.put("sendTime", sendTime);

            /*
             * 发送消息(交换机名称, 路由 routingKey, 消息主题内容
             */
            rabbitTemplate.convertAndSend("boot_topic_exchange", "blessing", messageMap);
            return "success";
        }catch (Exception e){
            e.printStackTrace();
            return "error";
        }
    }
}

启动成功后可在 127.0.0.1:9001/bootRabbitMq/send 发送消息。

消费者

application.yml

server:  
  port: 9002  
spring:  
  application:  
    name: consumer  
  rabbitmq:  
    host: 127.0.0.1  
    port: 5672  
    username: guest  
    password: guest

pom.xml

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

RabbitConsumer.class

@Component
@RabbitListener(queues = "boot_queue")  // 监听队列
public class RabbitConsumer {  
    @RabbitHandler  // 当有消息时,@RabbitHandler 可自动接收  
    public void listenMessage(Map messageContent) {  
        System.out.println("topicReceiver blessing:" + messageContent.toString());  
    }  
}

监听效果

监控.png

后台 后台.png

这样一个简单的兔子MQ demo 就完成啦。官网和各网站都有详细的介绍以及各种代码示例,RabbitMQ Tutorials — RabbitMQ.

现有 7 种消息传递方式,如简单模式、队列模式、发布/订阅模式、主题、可靠确认等。

2.png

总结 🐇

RabbitMQ 优点很多,社区活跃度高、功能完善,健壮、稳定、易用、跨平台、支持多种语言、文档齐全,兼具管理界面。

缺点是他的吞吐量较低,由 Erlang 编写,难以二次开发和维护。

但这有什么关系呢?兔子他不可爱吗,可爱就完事了🆗

🐇🐇🐇🐇🐇🐇🐇🐇