rabbitmq几种模式
simple 简单模式
work queue 工作队列模式
fanout 发布与订阅模式(交换机用fanout)
routing 路由模式 direct交换机
topics 主题模式 topic交换机 *代表一级 #可以0级或者多个 *.com.# xxx.com.xx.xx.xx.x
header 参数模式 direct交换机
p—list—c
p—list—c1,c2
p—x —list----c1 ,list2----c2
等
依赖包
1.java源生依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.10.0</version>
</denpendency>
2.spring依赖
<dependency>
<groupId>org.springframewokr.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>2.2.5.RELEASE</version>
</denpendency>
<dependency>
<groupId>org.springframewokr.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.2.5.RELEASE</version>
</denpendency>
3.springboot依赖
<dependency>
<groupId>org.springframewokr.boot</groupId>
<artifactId>spring-boot-start-amqp</artifactId>
</denpendency>
1.simple模式(简单模式)
1.生产者
Conntionfactory con=new Conntionfactory();
con.setHost("rabbitmq安装linux的ip");
con.setPort(“5672”);
con.setUserName("admin");
con.setPassword("admin");
con.setVirtualHost("./"); //虚拟让问节点
Sting queueName="队列名";
Connection connection =con.newConnection("生产者");
Channel channel= connection.createChannel();
channel.queueDeclare(queueName,false,false,false,null); //队列名 ,是否要持久化(消息是否存盘),排他性(是否独占),是否自动删除(最后一个消费者消费完后是否删除),携带一些附加参数
String msg="hello";
channel.basicPublish("交换机不指定会有默认",queueName,MessageProperties.PERSISTENT_TEXT_PLAIN,msg.getBytes());
finally{
if(channel!=null&&!=.isOpen()){
connection.close();
}
if(connection!=null&&connection.isOpen()){
connection.close();
}
}
2.消费者
//true autoack实际开发用false手动应答 不然会造成死循环
channel.basicConsume("queneName",true,new DeliverCallback(){
public void handle(String consumerTag,Delivery message) throws IOException{
sout("收到生产者的消息"+new String(message.getBody(),"UTP-8"));
//channel.basicQos(1); 写在外面
//channel.basicAck(message.getEnvelope().getDeliveryTag(),false); false表示获取单条
}
},new CancelCallback(){
public void handle(String consumerTag) throws IOException{
sout("接受失败");
}
})
2.fanout模式
1.生产者
Conntionfactory con=new Conntionfactory();
con.setHost("rabbitmq安装linux的ip");
con.setPort(“5672”);
con.setUserName("admin");
con.setPassword("admin");
con.setVirtualHost("./"); //虚拟让问节点
//!!!!!!!!!!区别
String exchangename = "fanout-exchange";
//路由key
String routingkey = "";
//指定交换机类型
String type="fanout";
Sting queueName="队列名";
Connection connection =con.newConnection("生产者");
Channel channel= connection.createChannel();
channel.queueDeclare(queueName,false,false,false,null); //队列名 ,是否要持久化(消息是否存盘),排他性(是否独占),是否自动删除(最后一个消费者消费完后是否删除),携带一些附加参数
String msg="hello";
channel.basicPublish("exchangename",routingkey,MessageProperties.PERSISTENT_TEXT_PLAIN,msg.getBytes());
finally{
if(channel!=null&&!=.isOpen()){
connection.close();
}
if(connection!=null&&connection.isOpen()){
connection.close();
}
}
2.消费者
写个tread 开启多个消费者
3.direct模式
String exchangename="directExchange";
//路由key
String routingkey = "xxx";
//指定交换机类型
String type="direct";
4.topic模式
String exchangename="topicExchange";
//路由key
String routingkey = "com.xxxx";
//指定交换机类型
String type="topic";
5.代码创建交换机并绑定
String exchangename="exchangename";
String exchangetype="direct";
channel.exchangeDeclare(exchangename,exchangetype,true); //true表示持久化交换机
//声明队列
channel.queueDeclare(queuename, 是否持久化true,排他性false,是否自动删除false,参数null);
//交换机绑定队列
channel.queueBind(queuename,exchangename,routkey)
6.work queue 工作队列模式 (轮训模式一人一个,公平分配模式能者多劳)
for像一个队列循环发送20次 ,默认轮训模式
什么是AMQP
高级消息队列协议,是应用层开发的一个标准,为面向消息中间件设计
springboot下Rabbitmq
配置
@Configuration
public class FanoutRabbitMqConfiguration{
//声明fanout交换机 同理 direct交换机 topic交换机
@Bean
public FanoutExchange fanoutExchange(){return new FanoutExchange("fanout_exchange")};
//声明队列 true代表持久化
@Bean
public Queue xxxqueue(){return new Queue("xxxxqueue",true)}
//交换机与queue绑定
//direct return BindingBuilder.bind(xxxqueue()).to(fanoutExchange().with("routkey")
@Bean
public Binding xxxBinding(return BindingBuilder.bind(xxxqueue()).to(fanoutExchange()) );
}
1.生产者
RabbitmqTemplate template= new RabbitmqTemplate()
template.convertAndSend(“交换机名”,"routkey",arg);
//需要配置一个RabbitMqConfiguration
2.消费者
//springboot提供不需要注解的绑定queue
//@RabbitListener(
bindings=@QueueBinding( value=@Queue(value="queueName"),durable="true",autoDelete="false" ) ,
exchange=@Exchange(value="topic_exchange",type=ExchangeTypes.TOPIC),
key="#.quename.*"
)
@RabbitListener(queues={"queuename"})
@Service
public class Consumer(){
@RabbitHandler
public void receiveMessage(String message){
sout(message);
}
}
TTL队列过期时间
表示消息设置的预期时间,消息只在队列中存在N秒,如果创建死信队列则移除到死信队列,否则直接丢掉
1.队列设置超时时间
@Bean
public Queue ttlqueue(){
Map<String,Object> args=new HashMap<>();
args.put("x-message-ttl",5000);//这里一定是int
return new Queue("ttlqueue",true,排他性false,自动移除false,args);
}
2.单独消息设置超时时间
@Bean
public Queue ttlmessagequeue(){
Map<String,Object> args=new HashMap<>();
args.put("x-message-ttl",5000);//这里一定是int
return new Queue("ttlqueue",true,排他性false,自动移除false,args);
}
1.发送消息
RabbitmqTemplate template= new RabbitmqTemplate()
MessagePostProcessor mesprc=new MessagePostProcessor(){
@Override
public Message postProcessMessage(Message message) throws AmqpException{
message.getMessageProperties().setExpiration("5000");
message.getMessageProperties().setContentEncoding("UTF-8");
return message;
}
}
template.convertAndSend(“交换机名”,"routkey",arg,mesprc);
死信队列
消息被拒绝,消息过期,队列长度达到最大的时候,消息会变成私信
配置
@Configuration
public class DeadRabbitMqConfiguration{
//声明fanout交换机 同理 direct交换机 topic交换机
@Bean
public DirectExchange directExchange(){return new DirectExchange("dead_exchange",true)};
//声明队列 true代表持久化
@Bean
public Queue deadqueue(){return new Queue("deadqueue",true)}
//交换机与queue绑定
//direct return BindingBuilder.bind(xxxqueue()).to(fanoutExchange().with("routkey")
@Bean
public Binding deadBinding(return BindingBuilder.bind(deadqueue()).to(directExchange()).with("dead") );
}
//正常队列绑定死信队列
@Bean
public Queue ttlqueue(){
Map<String,Object> args=new HashMap<>();
args.put("x-message-ttl",5000);//这里一定是int
args.put("x-max-length",5);//这里一定是int
args.put("x-dead-letter-exchange","dead_exchange");
args.put("x-dead-letter-routing-key","dead");
return new Queue("ttlqueue",true,排他性false,自动移除false,args);
}
rabbitmq内存控制
1.命令方式(重启后失效)
rabbitmqctl set_vm_memory_high_watermark relative 0.4
rabbitmqctl set_vm_memory_high_watermark absolute 50MB
2.配置文件方式
当前配置文件; /etc/rabbitmq/rabbitmq.conf
#默认
#vm_memory_high_watermark.relative=0.4
#使用relative相对值设置fraction 建议在0.4-0.7
vm_memory_high_watermark.relative=0.6
#绝对值
vm_memory_high_watermark.absolute=4GB
rabbitmq磁盘预警
末仍情况下磁盘预警为50MB,当磁盘空间第50MB被占用时,会阻塞生产者并停止内存消息换页到磁盘
这个阈值可以减小,但不能完全的消除因磁盘耗尽导致崩溃的可能性,比如在两次磁盘空间的检查空隙内,第一次检查是60mb,第二次检查就可能是1mb直接出现警告
1.通过命令行设置
rabbitmqctl set_disk_free_limit <disk_limit>
rabbitmqctl set_disk_free_limit memory_limit <fraction>
disk_limit:固定单位为KB MB GB
fraction:是相对阈值,建议范围在1.0-2.0之间(相对于内存)
2.配置文件
disk_free_limit.relative=2
disk_free_limit.absolute=50mb
内存换页
内存3G ,当队列里面大于0.5相当于1.5g的时候就会换页
vm_memory_high_watermark_paging_ratio =0.5
rabbitmq集群
当一个服务挂掉的时候可以用别的服务,提供稳定可靠的服务
1.单机多实例集群
场景:假设有两个rabbitmq节点,分别为r1,r2,r1作为主节点,r2作为从节点
启动命令:RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=r1 rabbitmq-server-detached
结束命令:rabbitmq -n rabbit -1 stop
2.第一步启动r1节点
sudo RABBITMQ_NODE_PORT=5672 RABBITMQ_NODENAME=r1 rabbitmq-server start &
.....starting broker 提示完成
3.第二步启动r2节点
注意:web管理插件端口占用,所以还要指定其web插件端口的port
RABBITMQ_SERVER_START_ARGS=“-rabbitmq_management listener [{port,15673}]”
sudo RABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener [{port,15673}]" RABBITMQ_NODENAME=r2 rabbitmq-server start &
4.启动验证ps -aux|grep rabbitmq
ps -aux|grep rabbitmq
5.设置r1为主节点 -n指节点名
sudo rabbitmqctl -n r1 stop_app//停止
sudo rabbitmqctl -n r1 reset //目的是清除历史数据
sudo rabbitmqctl -n r1 start_app //启动应用
6.设置r2从节点
sudo rabbitmqctl -n r2 stop_app//停止
sudo rabbitmqctl -n r2 reset //目的是清除历史数据
sudo rabbitmqctl -n r2 join_cluster r1@'Server-node'//将r2加入到r1 servernode更换成每一行开头的root@xxx
sudo rabbitmqctl -n r2 start_app //启动应用
7.验证集群
sudo rabbitmqctl cluster_status -n r1
web页面查看集群
1.默认情况没有web客户端插件,需要安装 默认情况只能本机登录需要配置一个远程登录用户
rabbitmq-plugins enable rabbitmq_management
rabbitmqctl -n r1 add-user admin admin
rabbitmqctl -n r1 set_user_tags admin administrator
rabbitmqctl -n r1 set-permissions -p / admin ".*" ".*" ".*"
登录页面ip:15673查看
注意 如果是 一台服务器部署一个主节点 另外一台部署从节点,必须把主节点的cookie复制到其他节点
cookie的存放位置:/var/lib/rabbitmq_erlang.cookie
sudo rabbitmqctl -n r2 join_cluster r1@‘Server-node’ //多机的时候servernode得换成ip或者别名
列入:主机分别为r1 r2
1.逐个启动节点
2.配置各节点的hosts文件 vim /etc/hosts
ip1: rabbit-1
ip2:rabbit-2
其他雷同单机部署