RabbitMQ是一套开源(MPL)的消息队列服务软件,是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现,由以高性能、健壮以及可伸缩性出名的 Erlang 写成.
我们说到 RabbitMQ 引入 Exchange 是为了实现消息的灵活路由,到底有哪些路由方式?
RabbitMQ 中一共有四种类型的交换机。
Exchange type | Default pre-declared names |
---|---|
Direct exchange (直连) | (Empty string) and amq.direct |
Fanout exchange(广播) | amq.fanout |
Topic exchange(主题) | amq.topic |
Headers exchange | amq.match (and amq.headers in RabbitMQ) |
Direct Exchange 直链模式 也是默认模式 (发布订阅模式 完全匹配)
Fanout exchange (广播模式) Fanout交换将消息路由到绑定到其的所有队列,并且忽略了路由键。体育赛事广播、游戏排行广播、分布式系统可以广播各种状态和配置更新、群聊
Topic exchange (主题,规则匹配)
一个队列与主题类型的交换机绑定时,可以在绑定键中使用通配符。支持两个通配符:
# 代表匹配 0 个或者多个单词
* 代表匹配不多不少一个单词
Headers Exchange
不常用
RabbitMQ 的持久化分为消息持久化、队列持久化、交换器持久化。无论是持久化消息还是非持久化消息都可以被写入磁盘。
非持久化消息在RabbitMQ宕机时会丢失,即使已写入磁盘也会删除。
队列、交换机持久化参数boolean durable
消息持久化 参数设置
// MessageProperties.PERSISTENT_TEXT_PLAIN
public static final BasicProperties PERSISTENT_TEXT_PLAIN =
new BasicProperties("text/plain",
null,
null,
2,
0, null, null, null,
null, null, null, null,
null, null);
}
即 deliveryMode = 2
// 百分比 fraction 建议 0.4~0.66
rabbitmqctl set_vm_memory_high_watermark
// 绝对值,固定大小,单位为 KB、MB、GB
rabbitmqctl set_vm_memory_high_watermark absolute
fraction 为内存阈值,默认是 0.4,表示 RabbitMQ 使用的内存超过系统内存的 40%时,会产生内存告警,重启会失效,永久生效需要修改配置文件。
vm_memory_high_watermark_paging_ratio=0.5
当换页阈值大于 1 时,相当于禁用了换页功能
rabbitmqctl set_disk_free_limit # limit 为绝对值,KB、MB、GB
rabbitmqctl set_disk_free_limit mem_relative # fraction 为相对值,建议 1.0~2.0 之间
# rabbitmq.conf
disk_free_limit.relative=1.5
# disk_free_limit.absolute=50MB
rabbitmq-plugins list # 查看
rabbitmq-plugins enable rabbitmq_management # 开启
rabbitmq-plugins disable rabbitmq_management #关闭
rabbitmqctl environment
生产者 MyProducer.java
消费者 MyConsumer.java
这里的3步在生产者和消费者执行都行,也可以在RabbitMQ管理后台手动新增和绑定。
一般我们本地测试先创建消费者,再等待生产者发送消息,所以这里在消费者执行生命。
//声明交换机
channel.exchangeDeclare(EXCHANGE_NAME,"direct",true);
//声明队列
channel.queueDeclare(QUEUE_NAME, false,false,false,null);
//绑定队列和交换机
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME,"");
import com.rabbitmq.client.*;
public class MyProducer {
private final static String QUEUE_NAME = "SIMPLE_QUEUE";
private final static String EXCHANGE_NAME = "LIAO_EXCHANGE";
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("43.142.129.217");
factory.setPort(5673);
factory.setVirtualHost("/");
factory.setUsername("admin");
factory.setPassword("admin");
try {
//创建连接
Connection conn = factory.newConnection();
//创建通道
Channel channel = conn.createChannel();
//声明交换机
// channel.exchangeDeclare(EXCHANGE_NAME,"direct",true);
//声明队列
//channel.queueDeclare(QUEUE_NAME, false,false,false,null);
//绑定队列和交换机
//channel.queueBind(QUEUE_NAME, EXCHANGE_NAME,"");
// 发送消息
String msg = "Hello world, Rabbit MQ";
channel.basicPublish( EXCHANGE_NAME,"liao.routingKey", null, msg.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
消费者
package com.liao.edu.mq.rabbitmq.simple;
import com.rabbitmq.client.*;
import java.io.IOException;
public class MyConsumer {
private final static String QUEUE_NAME = "LIAO_QUEUE";
private final static String EXCHANGE_NAME = "LIAO_EXCHANGE";
public static void main(String[] args) {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("43.142.129.217");
factory.setPort(5673);
factory.setVirtualHost("/");
factory.setUsername("admin");
factory.setPassword("admin");
try {
// 建立连接
Connection conn = factory.newConnection();
// 创建消息通道
Channel channel = conn.createChannel();
//生命交换机
channel.exchangeDeclare(EXCHANGE_NAME,"direct",false,false,null);
//生命队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//绑定交换机和队列
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"liao.routingKey");
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("consumerTag : "+consumerTag);
System.out.println("deliveryTag : "+envelope.getDeliveryTag());
System.out.println("received msg : "+new String(body,"utf-8"));
}
};
// 开始获取消息
channel.basicConsume(QUEUE_NAME,true,consumer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
申请了1个月的腾讯云服务,搭建的RabbitMQ服务。
http://43.142.129.217:15673/#/
admin/admin
过期前都可以用
# 拷贝插件
docker cp /rabbitmq_delayed_message_exchange-3.10.2.ez rabbitmq:/opt/rabbitmq/plugins/
# 进入容器内
docker exec -it rabbitmq bash
# 查看插件列表
rabbitmq-plugins list
# 开启插件支持
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
# 退出容器
ctrl + p +q
# 重启容器
docker restart rabbitmq