• 消息队列&中间件


    1.什么是消息队列?

    消息队列,我们一般称为MQ(Message Queue)。

    很多初学者认为MQ通过消息的发送和接受来实现程序的异步和解耦,但是实际上MQ的主要目的是通讯。

    MQ定义了发送者为生产者,接收消息的那一方为消费者。

    2.消息队列的主要作用。

    异步,削峰,解耦(重要)。

    业务场景

    假设一个下单的业务场景,用户在下单之后,需要依次完成扣减余额,扣减库存,通知商家,发送短信,发送京豆等业务。

    高可用: 如果其中一个服务宕机(这里的宕机不一定是服务器故障,更多指的是网络延迟,网络缓慢的问题),那么后面的业务都不能执行下去,业务之间的耦合度高。

    高并发: 线程数量是有限的,每次处理的请求数量是有限的。在QPS很高的情况,服务很容易被冲垮。

    高性能: 上面业务都是串行执行,假设网络传输200ms,业务20ms,完成上面这些操作就要耗时2s,用户的体验极差。并且下单之后业务越多,这个时间越长。

    传统设计

    在说明消息队列的优势之前,需要先明确传统设计的不足之处

    传统设计的思路使用于并发量小,业务体量小的场景下,我们可以很快定位到程序中的错误,这是优势,但当并发量增大的情况下,会产生问题(三高)。

    消息队列

    如果采用消息队列,再来审视上面三个问题。

    高可用: 其中一个模块宕机了,也不会影响其他模块。(假如库存系统宕掉了,那就等他好了之后再取消息消费,库存系统,短信服务还是各司其职)

    高并发: 消息队列不处理业务上的逻辑,每次下单只需要把订单消息放到消息队列里面,并且消息队列支持的并发是百万级的,就不需要担心服务被冲垮这回事。

    高性能: 用户下单,我们的逻辑就是放消息到消息队列中,请求很快就能返回,用户体验比较好。

    消息队列的优点

    解耦: 如上面高并发所说,一个服务宕了,不会影响其他服务。

    削峰: 假设平时服务只能撑起来几万QPS,当遇到淘宝京东的秒杀活动,服务器直接垮掉。但是有了消息队列,只需要将下单消息放到消息队列中,其他服务从里面取出来正常消费即可,不至于把服务压垮。类似是一个大坝无拦截上游的冲击力。

    异步: 连接消息队列的服务模块异步执行。多一个模块,不用改原来的代码,只相当于消息队列多一个消费者。

    消息队列的问题

    消息队列是完美的吗? 肯定不是,有优点就会有缺点。

    第一,在并发量不大的情况下没必要用,反而让系统设计更加复杂。

    第二,事务问题。也是最明显的问题。没办法保证所有业务都能执行成功,可能数据不一致(可能下单了,信息也发了,但是库存没减)。既然要用消息队列,就要接受这个问题的存在。只需要保证最终一致性,最终数据是正确的。

    第三,可用性。解耦说的是业务模块之间的解耦,但是如果消息队列挂了,会影响所有模块。也就是其他模块对消息队列的依赖性很严重。

    KafKa使用

    1.添加依赖。

    1. <dependency>
    2. <groupId>org.springframework.kafka</groupId>
    3. <artifactId>spring-kafka</artifactId>
    4. </dependency>

    2.yml配置

    1. spring:
    2. kafka:
    3. bootstrap-servers: 服务器ip:端口
    4. consumer:
    5. group-id: 组别名

    3.生产者

    1. @RestController
    2. public class KafKaController {
    3. @Autowired
    4. KafkaTemplate kafkaTemplate;
    5. @RequestMapping("/produce")
    6. public String producer(String message){
    7. kafkaTemplate.send("order",message);
    8. return "生产者生产消息";
    9. }
    10. }

    4.消费者监听

    1. @Component
    2. public class KafKaListen {//接收来自kafka的消息
    3. @KafkaListener(topics = "order")
    4. public void listen(ConsumerRecord record){
    5. System.out.println("接收到消息" + record.value());
    6. System.out.println("okk");
    7. }
    8. }

    ----未完待续----

  • 相关阅读:
    牛血清白蛋白BSA/人血清白蛋白HSA/卵清白蛋白OVA纳米粒偶联CTT2肽(作用机理)
    Notepad++安装插件和配置快捷键
    代码分割换行 处理元素中空白 white-space属性
    大模型应用 搭建本地知识库
    Vue/JS中定时器模拟随机指定范围、位数的小数并更新innerHTML以及页面被销毁时监听事件中销毁定时器
    影刀Rpa 、英佑科技面试总结
    【算法——双指针】LeetCode 18 四数之和
    记录一个删库跑路的技巧(如何快速删除数据库下面的所有表)
    RT-Thread Studio学习(十二)W25Q128(SPI)的读写
    这样也行,在lambda表达式中优雅的处理checked exception
  • 原文地址:https://blog.csdn.net/m0_59925573/article/details/136632941