1. RabbitMQ 简介
RabbitMQ是一个开源的AMQP实现,服务器端用erlang语言编写,支持多种客户端
Docker启动RabbitMQ
docker run -d --name myrabbitmq \
-e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin \
-p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 \
rabbitmq:management
相关端口
- 15672:web管理面页端口,需要management版本
- 5672:AMQP客户端端口,后台连接时使用
- 25672:用于rabbitMQ节点间和CLI工具通信
- 61613:当STOMP插件启用的时候打开,作为STOMP客户端端口
- 1883:当MQTT插件启用的时候打开,作为MQTT客户端端口
2. RabbitMQ 原理
基本模型
- Message:消息头(routing-key、priority、delivery-mode)+ 消息体
- Publisher:消息生产者
- Exchange:交换机,接收生产者的消息,根据路由键绑定队列,发送消息
- binding:根据路由键绑定交换机和消息队列的路由规则
- Queue:保存消息直到被消费者消费
- channel:共享一条TCP连接,建立多条虚拟信道,消息传递都通过信道完成
- Consumer:消息消费者
- Virtual Host:每个虚拟机都是一个消息队列服务器,拥有自己的设置互不影响
- Broker:消息队列服务器实体
3. Exchange(交换机)
交换机类型
- direct(直连):根据routing-key和binding-key的匹配发送消息到对应队列
- fanout(广播):不管路由键,把消息给所有与之绑定的队列都发送一份
- topic(模糊匹配):binding-key用通配符(# 和 *)与routing-key进行模糊匹配
headers
4. SpringBoot 使用 RabbitMQ
SpringBoot自动配置类对应可以配置的RabbitMQ属性
@ConfigurationProperties(
prefix = "spring.rabbitmq"
)
public class RabbitProperties {
private static final int DEFAULT_PORT = 5672;
private static final int DEFAULT_PORT_SECURE = 5671;
private String host = "localhost";
private Integer port;
private String username = "guest";
private String password = "guest";
private final RabbitProperties.Ssl ssl = new RabbitProperties.Ssl();
private String virtualHost;
private String addresses;
@DurationUnit(ChronoUnit.SECONDS)
private Duration requestedHeartbeat;
private int requestedChannelMax = 2047;
private boolean publisherReturns;
private ConfirmType publisherConfirmType;
private Duration connectionTimeout;
private final RabbitProperties.Cache cache = new RabbitProperties.Cache();
private final RabbitProperties.Listener listener = new RabbitProperties.Listener();
private final RabbitProperties.Template template = new RabbitProperties.Template();
private List<RabbitProperties.Address> parsedAddresses;
...
}
application.yml
spring:
application:
name: rabbitmq
rabbitmq:
host: 192.168.xxx.xxx
port: 5672
username: admin
password: admin
virtual-host: /
为了使发送和接收数据时以Json方式序列化,需要配置工具类
@Configuration
public class MyAMQPConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
测试发送消息和接收消息
@SpringBootTest
@RunWith(SpringRunner.class)
class RabbitmqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
//直连发送数据,指定队列获取消息
@Test
void directSend() {
rabbitTemplate.convertAndSend("amq.direct","codfish.news", new Person("张三", 28));
}
//广播发送数据,所有队列获取消息
@Test
void fanoutSend() {
rabbitTemplate.convertAndSend("amq.fanout","", new Person("李四", 30));
}
//接收数据
@Test
void receive() {
Object o = rabbitTemplate.receiveAndConvert("codfish.news");
System.out.println(o);
}
}
监听队列中新加入的消息
@Service
public class PersonService {
//监听消息队列,指定队列中收到消息后立刻执行方法
@RabbitListener(queues = "codfish.news")
public void receiveObj(Person person) {
System.out.println("codfish队列中收到新消息" + person);
}
@RabbitListener(queues = "codfish.news")
public void receiveMsg(Message message) {
//获取消息体
System.out.println("消息体" + message.getBody());
//获取消息头
System.out.println("消息头" + message.getMessageProperties());
}
}