rabbitmq的作用:
1.同步变异步
2.高内聚,低耦合
3.流量削峰
rabbitmq的通信是需要信道的,而不是tcp直接通信。
*交换器:用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
三种常见的交换器类型:direct(发布与订阅),fanout(广播),topic(主题,规则匹配)
*绑定:用户消息队列和交换器之间的关联,一个绑定是基于路由键将交换器和消息队列连接起来的路由法则,可以将交换器理解为一个由绑定构成的路由表。
*路由键:rabbitmq决定将消息投递到哪个队列的规则。队列通过路由键绑定到交换器。
消息发送到消息代理服务器时,消息将拥有一个路由键,即便是空的,rabbitmq也会将其和绑定使用的路由键进行匹配。如果相匹配,消息就会投递到该队列。如果不匹配,消息将会进入黑洞。
*连接:指rabbit服务器和服务建立的tcp连接。
*信道:信道是tcp里面的虚拟连接,例如:电缆相当于tcp,信道就是一条独立的光纤束,一条tcp连接上可以创建多条信道,是没有限制的。tcp一旦打开,就会创建amqp信道。无论是发布消息,接收消息,订阅队列,这些动作都是通过信道完成的。
*交换器和队列的关系:交换器是通过路由键和队列绑定在一起的。如果消息拥有的路由键跟队列和交换器拥有的路由键匹配,那么消息就会被路由到该队列中去,路由键可以理解为匹配的规则。
*rabbitmq为什么需要信道,而不是tcp直接通信:1.tcp创建和销毁开销大,创建需要三次握手,销毁需要四次分手。2.如果不用信道,那么应用程序就会tcp连接到rabbit服务器,高峰时每秒成千上万条连接会造成资源的巨大浪费,而且操作系统每秒处理tcp连接数也是有限的,必定会造成性能的瓶颈。3.信道的原理是一条线程一条信道,多条线程多条信道公用一条tcp连接,一条tcp连接可以容纳无限的信道,即使每秒成千上万的请求也不会造成性能的瓶颈。
*配置消息的发送者:
在配置类中注入AmqpTemplate,发送消息通过其convertAndSend方法来发送,方法中包含三个参数,要使用到的交换器,消息的路由键,消息的内容。
*配置消息的消费者:
在消费者的类上加入@RabbitListener注解。
ex:
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.log.info}",autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.direct.exchange}",type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.log.info.routing.key}"
)
)
其中@Queue中配置的是需要连接到的队列。autodelete为true时,在停掉消费者服务后,队列自动消失,停掉之后将不会接收已经发送的消息,将会导致丢失一部分消息,如果设置autodelete为false,在停掉消费者服务后,将不会丢失已经由发送者发送来的消息,再次启动消费者还会从上次的节点开始接收消息而不会造成消息的丢失。
@Exchange中配置的是交换器的信息,type表示交换器的类型(此处是发布与订阅模式)
key配置的是路由键的信息,表示拥有此路由键的消息将会被投递到该队列中。
---------------------------------------------------------------------------------------------------------------------
一种交换器只能由一种类别(DIRECT,TOPIC,FANOUT)
可以同时将不同的路由键以及交换器映射到同一个队列,不过这样会很麻烦。因为此队列会同时匹配多个交换器和路由键,当通过特定的交换器和路由键发送消息时,可能会被其他的消费者所接收到(交换器+路由键也指向该队列的)