RabbitMQ学习笔记

RabbitMQ

消息中间件:

1.利用可靠的传输机制在系统和系统间直接进行通信

2.通过提供消息传递和消息的排队机制,可以在分布式系统环境下扩展进程间的通讯

本质就是接受数据,接受请求,存储数据,发送数据等

应用场景:

1.跨系统的数据传递

2.高并发的流量削峰

3.数据的分发和异步处理

4.大数据分析与传递

5.分布式事务

原理

RabbitMQ使用的是AMQP协议

img

RabbitMQ Server: 也叫broker server,它是一种传输服务。 他的角色就是维护一条
从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输。

Producer: 消息生产者,如图A、B、C,数据的发送方。消息生产者连接RabbitMQ服
务器然后将消息投递到Exchange。

Consumer:消息消费者,如图1、2、3,数据的接收方。消息消费者订阅队列,
RabbitMQ将Queue中的消息发送到消息消费者。

Exchange:生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个
或多个Queue中(或者丢弃)。Exchange并不存储消息。RabbitMQ中的Exchange有
direct、fanout、topic、headers四种类型,每种类型对应不同的路由规则。

Queue:(队列)是RabbitMQ的内部对象,用于存储消息。消息消费者就是通过订阅
队列来获取消息的,RabbitMQ中的消息都只能存储在Queue中,生产者生产消息并最终
投递到Queue中,消费者可以从Queue中获取消息并消费。多个消费者可以订阅同一个
Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者
都收到所有的消息并处理。

RoutingKey:生产者在将消息发送给Exchange的时候,一般会指定一个routing key,
来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联
合使用才能最终生效。在Exchange Type与binding key固定的情况下(在正常使用时一
般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时,通过
指定routing key来决定消息流向哪里。RabbitMQ为routing key设定的长度限制为255
bytes。

Connection: (连接):Producer和Consumer都是通过TCP连接到RabbitMQ Server
的。以后我们可以看到,程序的起始处就是建立这个TCP连接。

Channels: (信道):它建立在上述的TCP连接中。数据流动都是在Channel中进行
的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。

VirtualHost:权限控制的基本单位,一个VirtualHost里面有若干Exchange和
MessageQueue,以及指定被哪些user使用

交换机

安装与启动

https://www.cnblogs.com/saryli/p/9729591.html

安装完成后 sbin目录下的rabitmq-server.bat即可启动rabitmq

默认端口5672

管理界面端口15672

账号密码都是guest 可以进入管理界面

注意这个guest只能本地登录 如果需要远程登录需要添加账号 授权

rabbitmqctl add_user admin admin
rabbitmqctl set_user_tags admin administrator

administrator即最高权限

工作模式

简单模式

一般使用默认交换机

Work queues

多个消费端消费同一个队列中的消息,队列采用轮询的方式将消息是平均发送给消费者;

一般使用默认交换机

特点:

1、一条消息只会被一个消费端接收;

2、队列采用轮询的方式将消息是平均发送给消费者的;

3、消费者在处理完某条消息后,才会收到下一条消息

publish/subscribe

使用fanout交换机

又叫发布订阅模式,该模式多了一个交换机,生产端先把消息发送到交换机,再由交换机把消息发送到绑定的队列中,每个绑定的队列都能收到由生产端发送的消息。

特点:

1、每个消费者监听自己的队列;

2、生产者将消息发给交换机,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都将接收到消息

应用场景:用户通知,当用户充值成功或转账完成系统通知用户,通知方式有短信、邮件多种方法;

Routing

使用direct交换机

Routing 模式又称路由模式,该种模式把交换机,队列,路由key绑定在一起,这样,生产端发送消息的时候指定routing key,通过routing key就可以把相应的消息发送到绑定相应routing key的队列中去。

特点:

1、每个消费者监听自己的队列,并且设置routingkey;
2、生产者将消息发给交换机,由交换机根据routingkey来转发消息到指定的队列;

应用场景:用户通知,当用户充值成功或转账完成系统通知用户,通知方式有短信、邮件多种方法;

Topics

使用topic交换机

Topics 模式和Routing 路由模式最大的区别就是,Topics 模式发送消息和消费消息的时候是通过通配符去进行匹配的。

使用header交换机

header模式与routing不同的地方在于,header模式取消routingkey,使用header中的 key/value(键值对)匹配队列。

RPC 模式

RPC即客户端远程调用服务端的方法 ,使用MQ可以实现RPC的异步调用,基于Direct交换机实现,流程如下:

1、客户端即是生产者也是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列。

2、服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果。

3、服务端将RPC方法 的结果发送到RPC响应队列。

4、客户端(RPC调用方)监听RPC响应队列,接收到RPC调用结果。

Springboot整合RabbitMQ

以订阅模式为例

1.引入依赖

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit-test</artifactId>
        <scope>test</scope>
</dependency>

2.配置RabbitMQ

spring:
  #配置rabbitMq 服务器
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: root
    password: root
    virtual-host: /

3.配置类

声明并绑定交换机,声明队列

@Configuration
public class RabbitMqConfiguration{
    //1.声明注册fanout模式的交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        //(交换机的名字,是否持久化,是否自动删除)
        return new FanoutExchange("fanout-exchange-1",true,false);
    }
    //2.声明队列
    @Bean
    public Queue smsQueue(){
        //(队列名,是否持久化)
        return new Queue("sms.fanout.queue",true);
    }
    //3.绑定队列与交换机
    @Bean
    public Binding smsBingding(){
        return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
    }
}

4.获取对象

@Autowired
private RabbtitTemplate rabbitTemplate;
//发送消息到交换机
//如果消息是个对象,这个对象需要能序列化
rabbitTemplate.convertAndSend(交换机名字,路由key/队列名称,消息内容);



//接收消息
@RabbitListener(queue={"队列名"})
@Service
public class Consumer{
    //表明把消息注入到传入的参数中,需要类型相同
    @RabbitHandle
    public void reviceMessage(String message){
        System.out.println(message)
    }
}

路由模式

//使用direct交换机
 @Bean
    public DirectExchange ditectExchange(){
        //(交换机的名字,是否持久化,是否自动删除)
        return new ditectExchange("direct-exchange-1",true,false);
//绑定时需要制定路由key
@Bean
public Binding smsBinding(){
    //制定路由key的名字
    return BindingBuilder.bind(smsQueue()).to(fanoutExchange()).with("sms");
}
rabbitTemplate.convertAndSend(交换机名字,路由key,消息内容);

TTL设置

给队列设置时间,如果消息超过时间没有被接受,就移除或移动到死信队列

//创建队列
@Bean
public Queue directQueue(){
    Map<String,Object> args=new HashMap<>();
    args.put("x-message-ttl",5000);//单位ms
    return new Queue("ttl.direct.queue",true,args);
}

也可以对消息单独设置

MessagePostProcessor messagepostprocesspr=new MessagePostProcessor(){
    @Override
    public Message postProcessMessage(Message message) throws AmqpException{
        message.getMessageProperties().setExpiration("5000");
        message.getMessageProperties().setContentEncoding("UTF-8");
        return message;
    }
};
rabbitTemplate.convertAndSend(交换机,队列,消息,messagepostprocesspr);
posted @ 2021-05-05 18:38  刚刚好。  阅读(107)  评论(0)    收藏  举报