和上文的es一样,平时比较忙,没时间弄csdn的各种格式,我直接cv我的笔记了,建议直接看我的笔记链接,有问题可以留言问我:
文档:rabbitMQ.note
链接:http://note.youdao.com/noteshare?id=7ec46d4b88823be2175dc7ea73eb2a2c&sub=90BEC604C1304C4392BC45B5184E1BE3
安装:https://blog.csdn.net/qq_39135287/article/details/95725385
卸载:https://www.cnblogs.com/kingsonfu/p/11023967.html
页面地址:http://47.108.146.34:15672/
我这里的版本是:rabbitmq:3.8.9 erlang:23.0
账号密码是:admin,admin
安装之后会说guest不能远程登录:
这里提示guest用户只能在本地登录,这个时候我们远程访问需要自己添 加用户和相应的权限。
添加用户:./rabbitmqctl add_user admin admin
这句话的意思是添加一个用户 账号是admin 密码是admin
添加权限:./rabbitmqctl set_permissions -p “/” admin “." ".” “.*”
这句的意思是给所有的虚拟机主机添加所有的权限
修改用户角色:./rabbitmqctl set_user_tags admin administrator
之后使用admin登录即可;
rabbitmq重启:
[root@iz2vceej7yes1arlt6mczgz sbin]# pwd
/usr/local/software/rabbitmq_software/rabbitmq_server-3.8.9/sbin
[root@iz2vceej7yes1arlt6mczgz sbin]# ./rabbitmq-server restart
rabbitmq启停:
rabbitmq的web界面端口为:15672
tcp通信端口 [ java程序 ] :5672
集群内部的通信端口:25672
一,直连模式:
直连模式下,如果消费者最后没有close通道,那么程序就会一直在监听消费,如果close了,那么在程序执行完成之后就会断开 注意:测试的时候应该是main方法,而不是test,记得改一下
注意:队列的持久话应该设置为true,因为在rabbitmq重启之后队列如果没有持久化,那么队列里的未消费的消息也会丢失,在设置了队列持久化之后,rabbitmq重启之后队列不会丢失,但是队列里的消息还是会丢失,所以需要在发送消息时给传递的消息的额外设置指定为下图的参数
参数:是否独占队列:指改队列只能由该链接自己使用,其他链接使用的话会直接报错
参数:是否在消息消费完成后删除该队列:在消息消费完成之后【消费者断开链接】就会删除该队列
二:工作队列
生产者还是在源源不断的先队列中生产消息,但是消费者可以有多个一起来消费消息
生产者:
消费者1:
消费者2:
默认平均分配数据:消费者消费的数据的数量都是平均的
因为ack确认机制,它不会等消息消费完了再确认,他是接收了就确认,导致可以在接收了5条数据,消费到第三条后程序挂了,那么第四条,第五条数据就会丢失
如果我们不想出现这种消息丢失的情况,可以将ack自动确认机制设置为false,同时每一个消费者一次只能消费一条数据【这种同时实现了那个消费者消费快,那个消费者就多消费,谁慢就少消费的权重的方式】:
三:fanout模式【广播】
创建fanout类型的交换机:
fanout的消费者1:
fanout中一条消息被多个消费者同时执行:【eg:登录之后需要同时增加积分,创建订单,那么积分服务和订单服务都会同时消费到这条消息】
第四种:Routing模式【路由】
在生产者发送消息的时候需要同时指定一个路由key,交换机通过这个路由key来决定将消息发送到哪一个队列之中供订阅了这个队列的消费者进行消费【eg:路由key为error的时候会将消息发送到队列2供消费者c2消费】
Direct模式的生产者:
Direct模式下的消费者:【绑定error临时队列】
Direct模式下的消费者2:【绑定了error,info,warning临时队列】
Routing模式下的topic模式 【动态路由模式】:
这个模式和上面的路由相比,就是不需要绑定非常多的队列,而是采用*这种方式来匹配,本质上是一样的
topic模式下的生产者:
消费者1:
springboot集成rabbitmq:
一:直连模式:【hello;没有交换机,直连】
生产者:
消费者;
x消费者设置是否持久化与自动删除:
二:工作模式【work】:没有交换机,直连
生产者:【向work队列发送work模型消息】
消费者:
三:广播:【fanout】
生产者:
消费者:
四:Routing模式【路由模式:directs】
生产者:
消费者:
五:topic模式【发布订阅模式:动态路由:topics】
生产者:
消费者:
rabbitmq队列里的消息如果一直不被消费的情况下默认会一直存在[已经持久化的情况下]
rabbitmq死信队列:
死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况:
消息被否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时requeue 属性被设置为false。
消息在队列的存活时间超过设置的TTL时间。
消息队列的消息数量已经超过最大队列长度。
那么该消息将成为“死信”。
“死信”消息会被RabbitMQ进行特殊处理,如果配置了死信队列信息,那么该消息将会被丢进死信队列中,如果没有配置,则该消息将会被丢弃。
死信队列:
consumer:
/**
- 消费者
- */
@Component
public class Consumer {
@Resource
private RabbitTemplate rabbitTemplate;
@RabbitListener(queues = “newQueue”)
public void topicConsumer(Message message,Channel channel) throws IOException {
System.out.println(“业务消费=============>>>>>>>>>>>>>>>>>>”);
System.out.println(new String(message.getBody()));
//确认消费===>>确认完成则删除 [false: true:]
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
//拒绝接收===>>>>>直接将消息进入死信队列
// channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
}
@RabbitListener(queues = "dieQueue")
public void dietopicConsumer(Message message,Channel channel) throws IOException {
System.out.println("死信消费=============>>>>>>>>>>>>>>>>>>");
System.out.println(new String(message.getBody()));
channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
}
producer:
/**
-
生产者
-
*/
@Component
@EnableScheduling
public class Producer {@Resource
private RabbitTemplate rabbitTemplate;
@Scheduled(cron = “0/5 * * * * ?”)
public void testMyRabbitmq(){//rabbitTemplate.convertAndSend("myexchanges","getway","向rabbitmq发送的消息"); // rabbitTemplate.convertAndSend("dieExchange","dieQueue","aaaaaaaaaaaaaaaaaaa"); rabbitTemplate.convertAndSend("newExchange","newRoutingKey","asdasdasdasd"); System.out.println("两个队列都发送完成");
}
}
QueueConfig:
@Configuration
public class QueueConfig {
//业务交换机
@Value("${spring.rabbitmq.exchange}")
private String exchange;
//业务交换机
@Bean(“newExchange”)
public Exchange liveExchange(){
return ExchangeBuilder.topicExchange(exchange).build();
}
//业务绑定
@Bean(“Binding”)
Binding liveBinding(@Qualifier(“newQueue”) Queue queue, @Qualifier(“newExchange”) Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(“newRoutingKey”).noargs();
}
//业务队列====>>>绑定死信队列
@Bean(“newQueue”)
public Queue deadQueue(){
return QueueBuilder.durable(“newQueue”)
.withArgument(“x-dead-letter-exchange”,“dieExchange”)
.withArgument(“x-dead-letter-routing-key”,“dieRoutingKey”)
.build();
}
//死信交换机
@Bean(“dieExchange”)
public Exchange dieExchange(){
return ExchangeBuilder.topicExchange(“dieExchange”).build();
}
//死信绑定
@Bean(“dieBinding”)
public Binding dieBinding(@Qualifier(“dieQueue”) Queue queue,@Qualifier(“dieExchange”)Exchange exchange){
return BindingBuilder.bind(queue).to(exchange).with(“dieRoutingKey”).noargs();
}
//死信队列
@Bean(“dieQueue”)
public Queue dieQueue(){
return QueueBuilder.durable(“dieQueue”).build();
}
业务操作: