消息队列:RabbitMQ

一、初识MQ

        1、什么是MQ

        MQ (MessageQueue) ,中文是消息队列,字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。

        常见的消息队列有:

吞吐量特别高的话建议用Kafka,吞吐量低的话用RabbitMQ和Kafka都可以。

        2同步通讯和异步通讯:

        同步调用的优点:

        时效性较强,可以立即得到结果

        同步调用存在的问题:

        耦合度高: 每次加入新的需求,都要修改原来的代码。

        性能下架: 调用者需要等待服务提供者响应,如果调用链过长则响应时间等于每次调用的时间之和。

        资源浪费: 调用链中的每个服务在等待响应过程中,不能释放请求占用的资源,高并发场景下会极度浪费系统资源。

        级联失败: 如果服务提供者出现问题,所有调用方都会跟着出问题,如同多米诺骨牌一样, 迅速导致整个微服务群故障。

        异步调用方案 (异步调用常见实现就是事件驱动模式)   

异步通讯的优点:

  • 服务解耦
  • 性能提升,吞吐量提高
  • 故障隔离
  • 流量削峰

异步通讯的缺点:

  • 依赖于Broker的可靠性、安全性、吞吐能力
  • 架构复杂了,业务没有明显的流程线,不好追踪管理

        异步通讯的流程:

        Broker就是一个事件代理者,如果有人支付了,Broker就会通知这三个服务,这就叫事件订阅;

        整个流程就是:支付服务发现有人支付成功就会发布一个事件出去,告诉Broker订单ID是什么,然后Broker就会去通知这三个服务,订单服务就会更新订单状态,仓储服务就会去完成库存扣减、发货,短信服务就会完成短信的发送。在整个过程中,支付服务完成事件发布以后就会立即结束自己的业务,可以去返回用户了,它并不需要去等待这三个服务去完成业务,所以说这三个服务什么时候去做,什么时候做完,支付服务都不会管。因此,这种方式就是异步方式。

3、什么是消息队列

        消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。

        消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。

4、RabbitMQ

        RabbitMQ是目前非常热门的一款消息中间件,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。不管是互联网大厂还是中小企业都在大量使用。

        RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。

5、AMQP协议

        提到RabbitMQ,就不得不提AMQP协议。AMQP协议是具有现代特征的二进制协议。是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。

6、Rabbitmq的六种模式

simple简单模式、work工作模式、publish/subscribe订阅模式、routing路由模式、topic 主题模式、RPC模式。

7、mq怎么解决消息被重复消费呢?

        这个问题其实可以换⼀种说法,就是如何解决消费端幂等性问题(幂等性,就是⼀条命令,任意多次执⾏所产⽣的影响均与⼀次执⾏的影响相同),只要消费端具备了幂等性,那么重复消费消息的问题也就解决了。

产生的原因:

(1)、生产者发送给消息队列以后,消息队列会应达给生产者,但是这个过程中,消息队列出问题了没有收到消息,那么生产者就会重复发生消息,这时就产生了重复消息。
(2)、生产者发生消息给消息队列,消息队列由于数量太大延迟了,生产者等待响应超时了,这时生产者又会从新发生消息给消息队列。
(3)、生产者和消息队列因网络问题引起,生产者会发起重试。这样也会产生重复消息。
(4)、其实主要原因就是,消息成功进入了消息队列,但是由于各种原因消息队列没有给生产者成功的返回值,而生产者又有重试机制这种情况下就会产生重复消息。

解决方式:

方式一 数据库唯一主键

        消息是做数据库的插入操作,给这个消息做一个唯一主键,那么就算出现重复消费情况,就会导致主键冲突,避免数据库出现脏数据。

方式二 推荐 redis

        给消息分配一个全局id,只要消费过该消息,将<id,message>以K-V形式写入redis。消费者开始消费之前,先去redis中查询有没有消费记录即可。
存储方式可以例如: MQ的ID作为Key,常用的UUID作为value.或者调换过来也可以。

8、什么是分布式事务?

                分布式事务,就是指不是在单个服务或单个数据库架构下,产生的事务,例如:

  • 跨数据源的分布式事务
  • 跨服务的分布式事务
  • 综合情况

        在数据库水平拆分、服务垂直拆分之后,一个业务操作通常要跨多个数据库、服务才能完成。例如电商行业中比较常见的下单付款案例,包括下面几个行为:

  • 创建新订单
  • 扣减商品库存
  • 从用户账户余额扣除金额

        完成上面的操作需要访问三个不同的微服务和三个不同的数据库。

        订单的创建、库存的扣减、账户扣款在每一个服务和数据库内是一个本地事务,可以保证ACID原则。

        但是当我们把三件事情看做一个"业务",要满足保证“业务”的原子性,要么所有操作全部成功,要么全部失败,不允许出现部分成功部分失败的现象,这就是分布式系统下的事务了。

        此时ACID难以满足,这是分布式事务要解决的问题。

9、分布式事务的6种解决方案

2PC

协调者询问参与者是否准备成功,参与者回复结果

如果事务在每个参与者身上都执行成功了,协调者会发通知让所有参与者提交事务,否则,协调者让所有参与者回滚事务

注意:(在准备阶段中,参与者执行了事务,但是并没有提交,只有在提交阶段,接受到协调者通知之后,才会进行提交或者回滚)

TCC(补偿事务)

1.采用补偿机制,针对每一个操作,都会注册一个与其对应的确认和补偿操作,它分为3个阶段

    (1)try阶段主要是对业务系统进行检测和资源预留

    (2)confirm阶段是对业务系统做确认提交,try阶段执行成功后开始执行confirm,默认cofirm是不会出错的,即try成功,confirm一定成功

    (3)cancal阶段是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放

2.优点:跟2PC比起来,实现以及流程相对简单一点,但是数据的一致性也比2PC差一点

3.缺点:缺点比较明细,在2,3步都有可能失败,TCC属于应用层的补偿方式,不是很好处理

本地消息表(异步确保)

1.本地消息表与业务数据表处于同一个数据库中,这样就能利用本地事务来保证在对这两个表的操作满足事务特性,并且使用了消息队列保证最终一致性

2.优点:一种非常经典的实现,避免了分布式事务,实现了最终一致性

3.消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理

3PC

3PC的出现是为了解决2PC的一些问题,相比于2PC,他在参与者中也引入了超时机制,并且新增一个阶段使得参与者可以利用这个阶段统一各自的状态

  3PC包含3个阶段,准备阶段,预提交阶段,提交阶段

  3PC的准备阶段协调者只会询问参与者的自身情况,而预提交阶段就是和2PC的准备阶段一样,除了事务的提交其他该做的都做好了,提交阶段就是和2PC一样不管哪个阶段有参与者返回失败都会宣布事务失败,和2PC一样

MQ消息事务

通过消息实现事务过程

最大努力通知

最大努力通知其实表明了一种柔性事务的思想

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值