rabbitMQ学习笔记

183 阅读5分钟

rabbitMQ学习笔记

1.特点:

1.1 开源 稳定 性能好

1.2 与spring AMQP完美结合 api丰富

1.3 保证数据不丢失的情况下做到高可用 高可靠

2.应用场景:

2.1 异步:将消息放到消息中间件 需要时进行处理

2.2 削峰:限制访问流量 返回对应的响应信息 避免服务因超负载而崩溃

2.3 解耦:通过发布 订阅模式 解决服务间的耦合

3.AMQP协议:

3.1 概念:是一个提供消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计

3.2 相关概念:

a.Server:接收客户端的连接,实现AMQP实体服务

b.Connection:连接,应用程序与Server的网络连接,TCP连接

c.Channel:信道,消息读写等操作在信道中进行。客户端可以建立多个信道,每个信道代表一个会话任务

d.Message:消息,应用程序和服务器之间传送的数据,消息可以非常简单,也可以很复杂。有Properties和Body组成。Properties为外包装,可以对消息进行修饰,比如消息的优先级、延迟等高级特性;Body就是消息体内容

e.Virtual Host:虚拟主机,用于逻辑隔离。一个虚拟主机里面可以有若干个Exchange和Queue,同一个虚拟主机里面不能有相同名称的Exchange或Queue

f.Exchange:交换器,接收消息,按照路由规则将消息路由到一个或者多个队列。如果路由不到,或者返回给生产者,或者直接丢弃。RabbitMQ常用的交换器常用类型有direct、topic、fanout、headers四种,后面详细介绍

g.Binding:绑定,交换器和消息队列之间的虚拟连接,绑定中可以包含一个或者多个RoutingKey

h.RoutingKey:路由键,生产者将消息发送给交换器的时候,会发送一个RoutingKey,用来指定路由规则,这样交换器就知道把消息发送到哪个队列。路由键通常为一个“.”分割的字符串,例如“com.rabbitmq”

i.Queue:消息队列,用来保存消息,供消费者消费

4.常用交换器

4.1 交换器类型:RabbitMQ常用的交换器类型有direct、topic、fanout、headers四种

4.2 四种类型交换器的功能特点:

4.2.1 Direct Exchange:将所有发送到该交换器的消息被转发到RoutingKey指定的队列中,也就是说路由到BindingKey和RoutingKey完全匹配的队列中

4.2.2 Topic Exchange:将所有发送到Topic Exchange的消息被转发到所有RoutingKey中指定的Topic的队列上面(Exchange将RoutingKey和某Topic进行模糊匹配,其中“”用来匹配一个词,“#”用于匹配一个或者多个词。例如“com.#”能匹配到“com.rabbitmq.oa”和“com.rabbitmq”;而"login."只能匹配到“com.rabbitmq”)

4.2.3 Fanout Exchange:不处理路由键,会把所有发送到交换器的消息路由到所有绑定的队列中。优点是转发消息最快,性能最好

4.2.4 Headers Exchange:不依赖路由规则来路由消息,而是根据消息内容中的headers属性进行匹配

5.rabbitmq安装(docker安装)

5.1 下载: docker pull rabbitmq:3.8.0-beta.4-management

5.2 安装镜像: docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.8.0-beta.4-management

6.mq的基本使用

springboot整合rabbitmq:

依赖:

        <!--rabbitmq-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

配置信息:

spring: 
  rabbitmq:
    host: 139.186.75.113
    port: 5672
    username: guest
    password: guest
    publisher-confirms: true

6.1 direct模式

说明:相当于是一种点对点的发送和接收 ,消息发送到'hello'这个队列上,则监听该队列的就会收到该队列的消息

6.1.1 配置队列:

@Configuration
public class RabbitConfig {
    @Bean
    public Queue queue(){
        return new Queue("hello");
    }
}

6.1.2 消息发送:

@Component
public class MessageSender {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void send(){
        String context = "hello " + format.format(new Date());
        System.out.println("Sender : " + context);
        this.rabbitTemplate.convertAndSend("hello", context);
    }
}

6.1.3 消息接收:

@Component
public class MessageReceive {

    @RabbitListener(queues = "hello")
    public void receiveMessage(String string){
        System.out.println("direct接收信息:"+string);
    }
}

6.2 topic模式

说明: 比如下面要举得这个例子 交换机设置为topic模式,生产者生成的消息的路由键值为goods.XXXX.其中XXXX,可能为add、delete、update、modify等. 队列一绑定的是goods.add,队列二绑定的是goods.#,这样的话,如果生产者生产一个路由键值为goods.add的消息,辣么2个队列都将会收到。如果生产者生成一个路由键值为goods.delete的消息,辣么只有1个队列将会收到.

6.2.1 配置队列:

@Configuration
public class RabbitConfig {

    @Bean(name = "delete")
    public Queue topicQueue1(){
        return new Queue("goods.delete");
    }

    @Bean(name = "add")
    public Queue topicQueue2(){
        return new Queue("goods.add");
    }

    @Bean
    public TopicExchange getTopicExchange(){
        return new TopicExchange("exchange");
    }

    @Bean
    public Binding bindExchange1(@Qualifier("delete") Queue queue, TopicExchange exchange){
       return BindingBuilder.bind(queue).to(exchange).with("goods.add");
    }

    @Bean
    public Binding bindExchange2(@Qualifier("add") Queue queue, TopicExchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("goods.#");
    }
}

6.2.2 发送消息:

@Component
public class MessageSender {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void sendTopic(){
        String context = "发送一个topic消息 " + format.format(new Date());
        System.out.println("Sender : " + context);
        /*param1:交换机名称;param2:路由键;param3:发送消息内容*/
        this.rabbitTemplate.convertAndSend("exchange","goods.update", context);
    }
}

6.2.3 接收消息:

@Component
public class MessageReceive {

    @RabbitListener(queues = "goods.delete")
    public void receiveMessage2(String string){
        System.out.println("goods.delete队列接收信息:"+string);
    }

    @RabbitListener(queues = "goods.add")
    public void receiveMessage3(String string){
        System.out.println("goods.add队列接收信息:"+string);
    }
}

6.3 fanout模式

说明:相当于一种广播模式 所有队列注册到交换机上 被监听的队列都能收到消息

6.3.1 配置队列:

@Configuration
public class RabbitConfig {

    @Bean(name="Amessage")
    public Queue AMessage() {
        return new Queue("fanout.A");
    }

    @Bean(name="Bmessage")
    public Queue BMessage() {
        return new Queue("fanout.B");
    }

    @Bean
    FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");//配置广播路由器
    }

    @Bean
    Binding bindingExchangeA(@Qualifier("Amessage") Queue AMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(AMessage).to(fanoutExchange);
    }

    @Bean
    Binding bindingExchangeB(@Qualifier("Bmessage") Queue BMessage, FanoutExchange fanoutExchange) {
        return BindingBuilder.bind(BMessage).to(fanoutExchange);
    }

}

6.3.2 发送消息:

@Component
public class MessageSender {

    @Autowired
    private AmqpTemplate rabbitTemplate;

    private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void sendFanout(){
        String context = "发送一个fanout消息 " + format.format(new Date());
        System.out.println("Sender : " + context);
        /*param1:交换机名称;param2:"";param3:发送消息内容*/
        this.rabbitTemplate.convertAndSend("fanoutExchange","", context);
    }
}

6.3.3 接收消息:

@Component
public class MessageReceive {

    @RabbitListener(queues = "fanout.A")
    public void receiveMessage4(String string){
        System.out.println("fanout.A队列接收信息:"+string);
    }

    @RabbitListener(queues = "fanout.B")
    public void receiveMessage5(String string){
        System.out.println("fanout.B队列接收信息:"+string);
    }
}

6.4 headers模式