目录
1. 6种消息队列模式
1.1. hello world
- 生产者直接将消息传入队列,不经过交换机,且仅有一个消费者;
- 提取了生产者和消费者获取连接对象和关闭资源部分作为公共部分,构建了工具类,并且通过静态代码块只在类加载的时候构建一个工厂;
- 重点学习了在生产者和消费者的channel.queueDeclare时的对列持久化机制,和对列中的消息消费完毕自动删除队列的机制,生产者的channel.basicPublish时的消息持久化机制(当然是要在对列持久化的基础上),以保证在rabbitmq重启时对列和消息是否会丢失;
- 持久化后的队列不可再通过channel.queueDeclare重复声明;
- 消费者需要定义值main函数的主线程中,如果使用junit测试函数会导致该进程被提前杀死;
- 消费者不需要关闭资源连接,因为要一直监听消息队列;
- 消息队列中的消息都是通过bytes存储的。
1.2. work queues
- 未防止消费者消费过慢导致队列中的消息阻塞,引入了多个消费者;
- 默认情况下,会将消息平均分配给每一个消费者;
- channel.basicConsume的第二个参数为消息自动确认。true时,消息在所有消费者调用前将消息平均分配给每个消费者,然后rabbitmq立即将队列中的消息删除,如果以后在某个消费者的消息未执行完时宕机了, 则已分配给他的且他未执行的消息丢失。
false时,即使消息被消费了,在rabbitmq中也不会立即删除该消息; - channel.basicQos(1);//设置每次分配给消费者1个消息,而不是在所有消费者消费前将所有消息全部分配掉,配合上边代码消息自动确认为false时使用;
- channel.basicAck(envelope.getDeliveryTag(), false);在真正执行完一条消息后,将该消息删除(设置删除多条消息为false),配合上上边代码消息自动确认为false时使用。
1.3. fanout
- 广播模型,用到交换机,交换机类型指定为fanout。
- 生产者和交换机相连,交换机通过临时队列和消费者相连,每个临时队列连接一个消费者,每个消费者都可以通过广播,得到同样的消息;
- 在生产者中,通道声明的是交换机channel.exchangeDeclare,消息发布时(channel.basicPublish)也要指定交换机的名称;
- 每个消费者中通道声明的也是交换机channel.exchangeDeclare;
- 在消费者中创建临时队列,然后将交换机和临时队列绑定;
- 然后通过临时队列,消费消息;
1.4. direct(routing)
- 这种模型是在fanout 的模型基础上进行的;
- 静态路由模型,在生产者向交换机发送消息时,为消息绑定一个route key,同时在交换机和临时队列绑定时,为临时队列也绑定一个route key,若某些临时队列的route key和消息的route key相同,则消息传入这些临时队列,未来被绑定这些临时队列的消费者消费;
- 交换机类型指定为direct;
- 一个队列可以绑定多个route key;
1.5. topic(topics)
- 这种模型是在direct 的模型基础上进行的;
- 动态路由模式,将消费者的临时队列绑定的route key设置为统配符,其他不变。这样可以保证某一类的消息到达指定临时队列。
1.6. rpc
- 没讲
2. SpringBoot整合RabbitMQ
- 首先在pom文件中引入rabbitmq的坐标,然后直接在java中注入RabbitTempalte即可,使用rabbitTemplate作为生产者发送消息;
- hello world和work queue模式下,由于不使用交换机,生产者中rabbitTemplate.convertAndSend中的routingKey表示队列名称。在消费者中,使用@RabbitListener指定监听器,其中包括队列名称,是否持久化,自动删除等,使用@RabbitHandler定义回调方法;
- fanout模式下,生产者不需要指定routingKey,因为创建的是临时队列,并且不需要给消息做路由关键字的标记。但需要在生产者中指定交换机名称,在消费者中指定交换机名称和类型;
- routing和topic模式下,生产者不需要指定routingKey,此时的routingKey表示的就是路由关键字。需要在生产者中指定交换机的名称,在消费者中指定交换机名称和类型以及关键字;
- 测试入口类@SpringBootTest(classes = RabbitmqSpringbootApplication.class)要指定入口类的Class对象,并且加上@RunWith(SpringRunner.class)//工厂类 注解
3. 集群
3.1. 普通集群(副本集群)
- 首先将多个rabbitmq服务同步.erlang文件,将多个rabbitmq的.erlang改为相同的。此时将多个rabbitmq挂在了同一个节点上;
- 将某个rabbitmq服务作为master,其余rabbitmq服务作为这个服务的slave,构建集群;
- 启动这些rabbitmq服务
- 特点:从机只能复制主机的交换机,而不能复制主机的队列消息。当主机宕机了,从机不能转移故障(失败自动切换)顶上去作为主机,虽主机宕机,从机也无法提供服务。从机就相当于主机的"快捷方式"而已。
- 普通集群在真正的生产中用的很少。
3.2. 镜像集群
- 在普通集群的基础上,将主从机通过镜像,挂在不同的节点上;
- 作为镜像的从机可以手动指定,作为镜像的从机可以直接被消费者消费,并在集群中所有机器同步。而不作为镜像的从机仅对主机做复制,以备主机宕机,而不可直接被消费者消费。一般是对所有从机做镜像;
- 也可以对某个队列指定策略做镜像;
- 在向主机的rabbitmq服务发送消息时,即使主机宕机了,但因为做了集群,虽然主机收不到消息,但集群内的其他机器能将消息加入队列。待主机恢复后,又会同步过来;
- 上一条中,当主机宕机后,和Redis一样,从机会自动升级为主机。而当主机恢复过来时,他会作为新主机的从机(江山易主);