点击上方 JAVA大贼船 ,选择 星标 公众号
第一时间获取精彩内容![2c01fd84d37716c40964b030b4273b0f.png](https://i-blog.csdnimg.cn/blog_migrate/b8c05bf844685ba8f7a8026996034bdd.jpeg)
前言
花了一周多的时间(周末去掉..捂脸)在工作之余写了两篇关于rabbitMq的内容,一篇是原生版的,一篇是springboot版的。初学者最好是看一下原声版更清晰一点,如果急于应用也可以直接看本文。本文内容较多,看完了五大消息模型的应用后还有进阶篇连着在一起,研究不太彻底请多多指教,好了,不打扰你们看了!
原生版传送门
rabbitMQ-springboot版
官方参考文档
核心基础概念
Server: 又称之为Broker,接受客户端的连接,实现AMQP实体服务。
Connection: 连接,应用程序与Broker的网络连接。
Channel: 网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道。客户端可以建立多个Channel,每个Channel代表一个会话任务。如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立TCP connection的开销。
Message:消息,服务器和应用程序之间传送的数据,由Message Properties和Body组成。Properties可以对消息进行修饰,比如消息的优先级,延迟等高级特性,Body就是消息体内容。
Virtual Host: 虚拟地址,用于进行逻辑隔离,最上层的消息路由。一个Virtual Host里面可以有若干个Exchange和Queue,同一个Virtual Host里面不能有相同名称的Exchange或者Queue。
Exchange:交换机,只有转发能力不具备存储消息能力,根据路由键转发消息到绑定的队列。
Binding: Exchange和Queue之间的虚拟连接,binding中可以包含routing key。
Routing key: 一个路由规则,虚拟机可以用它来确定如何路由一个特定消息。
Queue: 也可以称之为Message Queue(消息队列),保存消息并将它们转发到消费者。
引入依赖
org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-starter-amqp org.springframework.boot spring-boot-starter-web org.projectlombok lombok com.fasterxml.jackson.core jackson-databind org.springframework.boot spring-boot-starter-tomcat
配置
spring: rabbitmq: host: 127.0.0.1 username: admin123 password: 123456 virtual-host: /test
消息模型代码示例
关于一些方法的使用,参数属性说明都在代码中有注释
简单队列模型
示例图
![31b1f71d21ea588ffd0a3c0f0e0a0aac.png](https://i-blog.csdnimg.cn/blog_migrate/ed8908909a5fd9a2d9dc24b3d9644f67.png)
P(producer/ publisher):生产者,如寄快递
C(consumer):消费者,如收快递
红色区域:队列,如快递区,等待消费者拿快递
一句话总结
生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。
初始化队列
package com.ao.springbootamqp.config;import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.core.*;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Component;@Component@Slf4jpublic class RabbitMqConfig {
/*队列*/ public static final String TEST_QUEUE = "simple-amqp_queue"; /**声明队列 * public Queue(String name, boolean durable, boolean exclusive, boolean autoDelete) {
* this(name, durable, exclusive, autoDelete, (Map)null); * } * String name: 队列名 * boolean durable: 持久化消息队列,rabbitmq 重启的时候不需要创建新的队列,默认为 true * boolean exclusive: 表示该消息队列是否只在当前的connection生效,默认为 false * boolean autoDelete: 表示消息队列在没有使用时将自动被删除,默认为 false*/ @Bean(TEST_QUEUE) public Queue testQueue() {
return new Queue(TEST_QUEUE, true); }
发送消息类
package com.ao.springbootamqp.service;import com.ao.springbootamqp.config.RabbitMqConfig;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.amqp.AmqpException;import org.springframework.amqp.core.Message;import org.springframework.amqp.core.MessageDeliveryMode;import org.springframework.amqp.core.MessagePostProcessor;import org.springframework.amqp.core.MessageProperties;import org.springframework.amqp.rabbit.connection.CorrelationData;import org.springframework.amqp.rabbit.core.RabbitTemplate;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import org.springframework.util.StringUtils;import java.util.UUID;@Component@Slf4jpublic class RabbitMqService {
@Autowired private RabbitTemplate rabbitTemplate; /*发送消息到队列*/ public String sendQueue(Object payload){
return baseSend("", RabbitMqConfig.TEST_QUEUE, payload, null, null); } /** * MQ 公用发送方法 * * @param exchange 交换机 * @param routingKey 队列 * @param payload 消息体 * @param messageId 消息id(唯一性) * @param messageExpirationTime 持久化时间 * @return 消息编号 */ public String baseSend(String exchange, String routingKey, Object payload, String messageId, Long messageExpirationTime) {
/*若为空,则自动生成*/ if (messageId == null) {
messageId = UUID.randomUUID().toString(); } String finalMessageId = messageId; /*设置消息属性*/ MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
@Override public Message postProcessMessage(Message message) throws AmqpException {
/*消息属性中写入消息id*/ message.getMessageProperties().setMessageId(finalMessageId); /*设置消息持久化时间*/ if (!StringUtils.isEmpty(messageExpirationTime)){
message.getMessageProperties().setExpiration(messageExpirationTime.toString()); } /*设置消息持久化*/ message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT); return message; } }; /*构造消息体,转换json数据格式*/ Message message = null; try {
ObjectMapper objectMapper = new ObjectMapper(); String json = objectMapper.writeValueAsString(payload); MessageProperties messageProperties = new MessageProperties(); messageProperties.setContentEncoding(MessageProperties.CONTENT_TYPE_JSON); message = new Message(json.getBytes(), messageProperties); } catch (JsonProcessingException e) {
e.printStackTrace(); } /*表示当前消息唯一性*/ CorrelationData correlationData = new CorrelationData(finalMessageId); /** * public void convertAndSend(String exchange, String routingKey, Object message, * MessagePostProcessor messagePostProcessor, @Nullable CorrelationData correlationData) throws AmqpException * exchange: 路由 * routingKey: 绑定key * message: 消息体 * messagePostProcessor: 消息属性处理器 * correlationData: 表示当前消息唯一性 */ rabbitTemplate.convertAndSend(exchange, routingKey, message, messagePostProcessor, correlationData); return finalMessageId; }}
测试
发送消息
@SpringBootTestclass RabbitMqTest {
@Autowired private RabbitMqService rabbitMqService; @Test public void tt(){
String s = "顺丰快递"; rabbitMqService.sendQueue(s); }}
查看管理界面
![33bff7b099777ce6ab5c89375c84ebf4.png](https://i-blog.csdnimg.cn/blog_migrate/2ed54c83a811e40070a0ac9ba754327f.png)
可以看到,消息已经成功发送到服务器上啦,里面消息的属性也正是我们设置好的。因为消息已经发送到服务器上啦,