Day129 消息中间件

31 篇文章 0 订阅

消息中间件

基础知识

  • 消息队列 MQ

    • 为什么:当数据进行更新时,数据库,索引库,静态页面都需要进行修改,如果直接让服务器端修改这些代码,违背了微服务的独立原则;即使通过接口进行修改也会导致代码的耦合,所以产生了消息队列的机制,如果数据发生修改,服务器端只需要向消息队列发送消息,就可以做其他工作了(异步),而索引库和静态页面的接口时刻监听消息队列,如果监听到服务端的消息便进行数据的更新。
      • 好处1:通过异步处理提高系统性能
      • 好处2: 降低系统耦合性
    • 是什么:消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。
    • 怎么实现:AMQP协议、Java提供的JMS接口。
      • JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
      • JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
      • JMS规定了两种消息模型;而AMQP的消息模型更加丰富
  • 缺点

    • 系统可用性降低:系统可用性在某种程度上降低,为什么这样说呢?在加入 MQ 之前,你不用考虑消息丢失或者说 MQ 挂掉等等的情况,但是,引入 MQ 之后你就需要去考虑了。
    • 系统复杂性提高:加入 MQ 之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题。
    • 一致性问题:我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了!
  • 常见MQ产品

    • ActiveMQ:基于JMS,最早大家都用 ActiveMQ,现在用的不多了
    • RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好,开源社区活跃,用的比较多,但可惜不是java开发的,适合中小型公司
    • RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会,大型公司能驾驭。
    • Kafka:分布式消息系统,高吞吐量,大数据领域必备。
      **加粗样式**
      MQ常见问题
  • 消息的顺序问题:消息有序指的是可以按照消息的发送顺序来消费。解决方法:保证生产者 - MQServer - 消费者是一对一对一的关系

  • 消息的重复问题:如果消费端收到两条一样的消息,应该怎样处理?解决方法:消费端处理消息的业务逻辑保持幂等性。

  • 幂等性: 多次请求,结果保持一致。比如多次付款,只成功一次。解决方案有全局ID,业务ID,雪花算法。

RabbitMQ

RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。 在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。
RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。

  • 核心组件
    • Exchange: 就是顺丰和韵达。
    • routingkey: 就是邮件地址的概念.
    • queue: 就是邮箱接收软件,但是可以接收多个地址的邮件,通过bind实现。
    • producer: 消息生产者,就是投递消息的程序。
    • consumer:消息消费者,就是接受消息的程序。
    • channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。

Broker: 简单来说就是消息队列服务器实体
Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
VHost: vhost 可以理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的 queue、exchange 和 binding 等,但最最重要的是,其拥有独立的权限系统,可以做到 vhost 范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的 vhost 中)。
Producer: 消息生产者,就是投递消息的程序
Consumer: 消息消费者,就是接受消息的程序
Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务
由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。

RocketMQ

  • 核心组件:主要由NameServer、Broker、Producer以及Consumer四部分构成。
    • Producer:消息的发送者(发信者)
    • Consumer:消息的接受者(收信人)
    • Broker:暂存和传输消息的服务器端(邮局)
    • NameServer:管理Broker(各个邮局的管理机构)
      在这里插入图片描述

https://www.jianshu.com/p/16c34951a6c4

ActiveMQ

Kafka

  • 核心组件:

    • Topic :消息根据Topic进行归类
    • Producer: 消息生产者,就是向kafka broker发送消息的客户端
    • Concumer:消息消费者,向kafka broker拉取消息的客户端
    • Broker:Kafka集群包含一个或多个服务器,这种服务器被称为broker
    • Zookeeper:依赖集群保存meta信息。
    • Partition:一个Topic分为多个Partition
    • Leader&Follower:消息备份
      *
  • 原理

  • 怎么保证数据不丢失这个问题要从3个方面来保证数据不丢失,生产者、服务端、消费者。

    • 生产端是如何保证数据不丢失的:
      • ack的配置
        • ack=0:生产者发送消息之后 不需要等待服务端的任何响应,丢失就丢失了。
        • acks = 1(默认值):生产者发送消息之后那么它就会收到来自服务端的响应。
        • acks = all (或-1):生产者在发送消息之后,需要等待ISR中所有的副本都成功写入消息之后才能够收到来自服务端的成功响应,在配置环境相同的情况下此种配置可以达到最强的可靠性。
      • retries的配置:在kafka中错误分为2种,一种是可恢复的(retries > 0),另一种是不可恢复的。
      • 高可用型:acks = all,retries > 0
      • 折中型:acks = 1 retries > 0
      • 高吞吐型:acks = 0
    • 消费端是如何保证数据不丢失的
      对于一个新的consumer加入到消费时,肯定会隶属于哪个组,只有这样才能消费数据auto.offset.reset = earliest(最早) /latest(最晚)

在consumer消费阶段,对offset的处理,关系到是否丢失数据,是否重复消费数据,因此,我们把处理好offset就可以做到exactly-once && at-least-once(只消费一次)数据。
当enable.auto.commit=true时 表示由kafka的consumer端自动提交offset,当你在pull(拉取)30条数据,在处理到第20条时自动提交了offset,但是在处理21条的时候出现了异常,当你再次pull数据时,由于之前是自动提交的offset,所以是从30条之后开始拉取数据,这也就意味着21-30条的数据发生了丢失。当enable.auto.commit=false时    
由于上面的情况可知自动提交offset时,如果处理数据失败就会发生数据丢失的情况。那我们设置成手动提交。    
当设置成false时,由于是手动提交的,可以处理一条提交一条,也可以处理一批,提交一批,由于consumer在消费数据时是按一个batch来的,当pull了30条数据时,如果我们处理一条,提交一个offset,这样会严重影响消费的能力,那就需要我们来按一批来处理,或者设置一个累加器,处理一条加1,如果在处理数据时发生了异常,那就把当前处理失败的offset进行提交(放在finally代码块中)注意一定要确保offset的正确性,当下次再次消费的时候就可以从提交的offset处进行再次消费。

2、确保消息不会被重复消费

3、消息送达确认怎么做

4、保证数据的可靠性

https://www.bilibili.com/video/BV1AA411q7PK?p=5
https://www.bilibili.com/video/BV1iE411t7cm?from=search&seid=10823313664557282619

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值