day4 MQ基础

MQ

1. 调用的方式-掌握

1. 同步调用
  • 优点:时效性较强,可以立即得到结果
  • 缺点:耦合度高、性能和吞吐能力下降、有额外的资源消耗、有级联失败问题
2. 异步调用
  • 优点:
    • 吞吐量提升:无需等待订阅者处理完成,响应更快速

    • 故障隔离:服务没有直接调用,不存在级联失败问题

    • 调用间没有阻塞,不会造成无效的资源占用

    • 耦合度极低,每个服务都可以灵活插拔,可替换

    • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

  • 缺点
    • 架构复杂了,业务没有明显的流程线,不好管理
    • 需要依赖于Broker的可靠、安全、性能

2. MQ的基本介绍

1. 什么是MQ
  • 掌握
  • 存放消息的队列。就是事件驱动架构中的Broker
2. 常见的MQ的产品有哪些?
  • 掌握

image-20220924134544469

追求可用性:Kafka、RocketMQ、RabbitMQ

追求可靠性:RabbitMQ、RocketMQ

追求吞吐能力:RocketMQ、Kafka

追求消息低延迟:RabbitMQ、Kafka

3. 为什么在这个业务中需要使用MQ,为什么选择RabbitMQ或者Kafka
  • 面试题
  • 为什么:完成异步,解耦,削峰
  • 为什么选择RabbitMQ:
    • 开发语言,Erlang,为异步而生
    • 消息延迟 微秒级
    • 消息可靠性 高

Kafka:

  • 单击吞吐量非常高
4. MQ的消息类型有哪些
    1. 不使用交换机
    • 简单队列
    • 工作队列:WorkQueue
    1. 使用交换机
    • 广播:Fanout
    • 路由:Direct
    • 主题:Topic
  • MQ中的常见的消息类型有哪些?

    • 面试题
      image-20220924134659341

3. MQ消息的发送和接收-重点掌握

1. 简单队列

image-20220924134812018

    1. 发送消息
      1. 导入amqp的依赖
    <!--AMQP依赖,包含RabbitMQ-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    
    • 2, 完成mq的配置
spring:
  rabbitmq:
    host: 192.168.150.101 # 主机名
    port: 5672 # 端口
    virtual-host: / # 虚拟主机
    username: itcast # 用户名
    password: 123321 # 密码
    1. 编写测试类
      1. 测试类上添加2个注解
      1. 通过@Autowired注入RabbitTemplate对象
      1. 发送消息
      • rabbitTemplate.convertAndSend(“队列名称”, " 消息");
@SpringBootTest
public class SpringAmqpTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSimpleQueue() {
        // 队列名称
        String queueName = "simple.queue";
        // 消息
        String message = "hello, spring amqp!";
        // 发送消息
        rabbitTemplate.convertAndSend(queueName, message);
    }
}
    1. 消费者消费消息
      1. 导入amqp的依赖
    • 2, 完成mq的配置
      1. 编写一个消费者的类
@Component
public class SpringRabbitListener {
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueueMessage(String msg) throws InterruptedException {
        System.out.println("spring 消费者接收到消息:【" + msg + "】");
    }
}
2. 工作队列模式

image-20220924134843775

让多个消费者绑定到一个队列,共同消费队列中的消息

    1. 生产者
    • 本质跟简单队列一样
    1. 消费者
      1. 编写多个消费者监听同一个队列
      1. 多个消费者之间对于同一个消息是竞争关系
      1. 对于多个消费者来说消息分配的时候使用的是平均分配、
@RabbitListener(queues = "simple.queue")
public void listenWorkQueue1(String msg) throws InterruptedException {
    System.out.println("消费者1接收到消息:【" + msg + "】" + LocalTime.now());
    Thread.sleep(20);
}

@RabbitListener(queues = "simple.queue")
public void listenWorkQueue2(String msg) throws InterruptedException {
    System.err.println("消费者2........接收到消息:【" + msg + "】" + LocalTime.now());
    Thread.sleep(200);
}
能者多劳:
spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息
3. 广播模式

image-20220924134906440

    1. 编写一个配置类完成交换机 队列 绑定关系的申明
    • 声明交换机
      
      • @Bean
        
        public FanoutExchange fanoutExchange(){
        return new FanoutExchange(“itcast.fanout”);
        }
    • 队列
      
      • @Bean
        
        public Queue fanoutQueue1(){
        return new Queue(“fanout.queue1”);
        }
    • 绑定队列和交换机
      
      • @Bean
        
        public Binding binding1(Queue fanoutQueue1, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
        }
    1. 编写多个消费者监听不同的队列
    1. 生产者发送消息到交换机
    • rabbitTemplate.convertAndSend(“itcast.fanout”,“”, "hello fanout ");
    • 易错点:routingkey只能是双引号的空不能是null
4. 路由模式

image-20220924134928468

    1. 使用注解的方式申明交换机 队列 绑定关系
    /**
     * Direct路由
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "direct.queue1"),
            exchange = @Exchange(name = "itcast.direct",type = ExchangeTypes.DIRECT),
            key = {"red","yellow"}
    ))
    public void listenDirectQueue1(String msg){
        System.out.println("消费者1接收到direct.queue1的消息:"+ msg);
    }
  • 推荐使用注解
    
  • 2. 编写生产者
    
    @Test
    void testSendDirectExchange() {
        //队列名称
        String queue = "itcast.direct";
        //消息
        String msg = "hello 大角牛";
        //发送消息
        rabbitTemplate.convertAndSend(queue, "yellow", msg);
    }
  • 注意发送的routingkey
5. 主题模式

image-20220924134949121

    1. 使用注解的方式申明交换机 队列 绑定关系
  @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "topic.queue2"),
            exchange =@Exchange(name = "itcast.topic",type = ExchangeTypes.TOPIC) ,
            key = "#.news"
    ))
    public void listenTopicQueue2(String msg){
        System.out.println("消费者接收到topic.queue2的消息:"+msg);
    }
    1. 编写生产者
rabbitTemplate.convertAndSend(queue,"plus.news",msg);
  • 注意发送的routingkey
6. 发送对象消息

JDK序列化方式并不合适。我们希望消息体的体积更小、可读性更高,因此可以使用JSON方式来做序列化和反序列化。

在publisher和consumer两个服务中都引入依赖:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.10</version>
</dependency>

配置消息转换器。在启动类中添加一个Bean即可:

@Bean
public MessageConverter jsonMessageConverter(){
    return new Jackson2JsonMessageConverter();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值