Mq学习笔记

MQ学习笔记

进程间通信方式

在学习进程间通信的时候,对了解到进程间通信的方式,主要有
管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。管道的本质是一段缓冲区。
命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信.命名管道的名字对应一个磁盘索引节点,有了这个名字任何进程有响应的权限都可以对他进行访问。
消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。
共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。共享内存则只拷贝两次:一次从输入文件到共享内存区,另一次从共享内存到输出文件。
信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。用于实现进程间的互斥与同步。
套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

对于消息队列的了解仅限于 是一种进程间通信的方式,生产者往队列中添加数据和消费数据是解耦的。

消息队列的作用

解耦:不用关心下游的数据处理结果
冗余: 消息队列会把数据持久化直到他们被完全处理,通过这一方式规避了数据丢失的风险。
扩展性:因为解耦了处理过程,如果想增大消息入队和处理频率,只要另外增加处理过程即可。
灵活性&峰值处理能力:面对突发流量,消息队列能够使关键组件顶住增长的访问压力,而不会因为超出负载请求而完全奔溃
可恢复性:当体系的一部分组件失效,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。而这种允许重试或者延后处理请求的能力通常是造就一个略感不便的用户和一个沮丧透顶的用户之间的区别。
送达保证
排序保证
缓冲
理解数据流
异步通信

消息队列的缺点:

系统可用性降低:
如果mq挂了,整个系统就奔溃了
数据一致性问题:
异步处理时,如果下游某一步没有成功,数据不一致。(分布式事务的方式解决)
系统复杂性提高:
加入了mq。需要考虑更多的问题,消息丢失,信息怎么保证不被重复消费。怎么保证消息传递的顺序性。
重复消费的解决:重复消费的情况是当异步过程中有一个环节失败了,会有重试机制,在重发一次时,因为其他服务也同样在监听这个消息,所以会有重复消费。通过幂等可以解决一个问题。
幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。通俗点讲:同样的参数调用接口,调用多少次结果都是一样的。
强校验:先查询有没有这个记录,如果没有往下进行,通过事务的方式,成功一起成功,失败一起失败。如果有记录,证明已经加过了,直接返回就可以了。
弱校验:这个简单,一些不重要的场景,比如给谁发短信啥的,我就把这个id+场景唯一标识作为Redis的key,放到缓存里面失效时间看你场景,一定时间内的这个消息就去Redis判断。
消费顺序:
使用hash取模的方式,将同一个订单发送到了同一个队列中,再使用同步发送保证发送有序。

分布式事务:

2pc(两段式提交)
3pc(三段式提交)
TCC(Try、Confirm、Cancel)
最大努力通知
XA
本地消息表(ebay研发出的)
半消息/最终一致性(RocketMQ)

2pc(两段式提交):通过消息中间件协调多个系统,在两个系统操作事务的时候都锁定资源但是不提交事务,等两者都准备好了,告诉消息中间件,然后再分别提交事务。(还是有可能失败)
在这里插入图片描述

最终一致性
在这里插入图片描述

整个流程中,我们能保证是:
业务主动方本地事务提交失败,业务被动方不会收到消息的投递。
只要业务主动方本地事务执行成功,那么消息服务一定会投递消息给下游的业务被动方,并最终保证业务被动方一定能成功消费该消息(消费成功或失败,即最终一定会有一个最终态)。

信息队列的应用场景

异步处理:
应用间并发处理消息,相比串行处理,减少处理时间。提升了服务性能
应用解耦:
多应用通过消息队列对同一消息进行处理,避免了调用接口失败导致整个过程失败
流量削锋:
应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况
日志处理
消息通讯:
消息模型:(一)点对点;(二)发布订阅

如何保证数据不会丢失

消息的丢失可能会出现在三个地方:
生产者弄丢数据
生产者将数据发送到RabbitMQ的时候,可能数据就在半路给搞丢了,因为网络啥的问题,都有可能。怎么解决?
①事务:生产者发送数据之前开启RabbitMQ事务(channel.txSelect),然后发送消息,如果消息没有成功被RabbitMQ接收到,那么生产者会收到异常报错,此时就可以回滚事务(channel.txRollback),然后重试发送消息;如果收到了消息,可以提交事务(channel.txCommit)。但是问题是,RabbitMQ事务机制一搞,基本上吞吐量会下来,因为太耗性能。
②confirm模式:在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的id,然后如果写入了RabbitMQ中,RabbitMQ会给你回传一个ack消息,告诉你说这个消息ok了。如果RabbitMQ没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息id的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。
所以一般在生产者这块避免数据丢失,都是用confirm机制的。
MQ弄丢数据
就是RabbitMQ自己弄丢了数据,这个你必须开启RabbitMQ的持久化,就是消息写入之后会持久化到磁盘,哪怕是RabbitMQ自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。
设置持久化有两个步骤:
①第一个是创建queue和交换器的时候将其设置为持久化,这样就可以保证RabbitMQ持久化相关的元数据,但是不会持久化queue里的数据;
②第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,此时RabbitMQ就会将消息持久化到磁盘上去
必须要同时设置这两个持久化才行
持久化可以和生产者的confirm结合,当持久化成功后,再ack生产者。如果持久化之前RabbitMQ挂了,生产者没收到ack,会重发。
消费者弄丢数据
RabbitMQ如果丢失了数据,主要是因为你消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,那么就尴尬了,RabbitMQ认为你都消费了,这数据就丢了。
这个时候得用RabbitMQ提供的ack机制,简单来说,就是你关闭RabbitMQ自动ack,可以通过一个api来调用就行,然后每次你自己代码里确保处理完的时候,再程序里ack一把。这样的话,如果你还没处理完,不就没有ack?那RabbitMQ就认为你还没处理完,这个时候RabbitMQ会把这个消费分配给别的consumer去处理,消息是不会丢的。

RocketMq

在这里插入图片描述

Producer:消息生产者,作用就是发消息。
Consumer:消息消费者,作用就是消费生产者发的消息。
Consumer Group:消费者组,订阅了相同Topic的多个 Consumer 实例组成一个消费者组。
Topic:Topic 是一种消息的逻辑分类,是生产者在发送消息和消费者在拉取消息的类别。
Message: 就是我们发的消息,一个 Message 必须指定 Topic。
Name Server:为 Producer 和 Consumer 提供路由信息。
Broker:接收来自生产者的消息,储存以及为消费者拉取消息的请求做好准备。 Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master。
BrokerName和BrokerId:Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。
Queue:是Topic在一个Broker上的分片等分为指定份数后的其中一份,是负载均衡过程中资源分配的基本单元。
下图描述了Topic,Broker和Queue的关系,MyTopic第一次分片,将消息存放在BrokerA和BrokerB中,Broke本身又对消息进行二次分片,存到了四个不同的Queue队列中。
在这里插入图片描述

Nameserver协调者

对Topic和路由信息进行管理。单个NameServer节点中存储所有Broker列表(包括master和slave)并和Broker保持长链接心跳。主要功能:注册发现,路由剔除。

Producer生产者

负责产生消息
在这里插入图片描述

Consumer消费者

负责消费消息
Consumer 订阅了 某个 Topic,当 Producer 发该 Topic的消息时,Consumer 就能收到该条消息。
消费模式分为:广播模式和集群模式。
广播消费指的是:一条消息被多个Consumer消费,即使这些Consumer属于同一个ConsumerGroup
集群消费模式:一条消息只能被ConsumerGroup里面的一个Consumer消费。
在这里插入图片描述

Broker消息存储

负责存储消息,转发消息
主流的MQ队列采取的存储方式:
(1)分布式KV存储
(2)文件系统
(3)关系型数据库DB
从存储效率来说, 文件系统>分布式KV存储>关系型数据库DB,直接操作文件系统肯定是最快和最高效的,但是如果从可靠性来讲的话,关系型数据库DB>分布式KV存储>文件系统。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值