MQ总结归纳

54 篇文章 0 订阅
48 篇文章 0 订阅

首先为什么要用mq
1应用系统服务接耦合 通过mq把同步调用改成异步调用
2实现缓存流量消峰
3 数据分发:跟应用解耦思想一致 只需要发送到mq 需要消费的服务去mq取 不需要消费的时候就自己关闭消费
缺点:
1降低了系统的可用性 mq挂了就都挂了
-》需要保证mq的高可用性
2系统复杂度变高 :怎么防止重复消费相同的消息(幂等性)、消息丢失处理、如何保证消息的顺序消费??
3一致性问题:怎么保证所有消费的系统数据是一致的?
其实共同的缺点在分布式的系统当中都是存在的 就是cap:分区容错性 一致性 可用性

在这里插入图片描述
在这里插入图片描述

**

RocketMq

**
阿里 2016年MQ中间件 阿里内部利用其处理双十一等高并发场景 可以处理万亿级别的消息

结构:
1消息从producer  先找nameserver(broker的管理者 相当于注册中心 broker要主动上报自己的信息到nameserver)去获取一个broker的地址 然后发送到 broker,consumer也从nameserv里面拿到地址 去broker取
	topic :消息的种类 发送者接受者都可以发送接受一个或者多个topic
	message queue:topic的分区 用于并行发送接受消息

集群:
nameserv: 无状态 每个节点信息一致,启动集群后broker会给每一个nameserv发送节点信息,所以nameserv集群内部的节点不需要同步信息(新加入一个nameserv broker会给这个新的nameserv发送节点信息!)  直接启动几个nameserv就可以
					需要保存topic和broker的映射
					新加一个节点也不用重启整个集群 broker会自动对新的nameserv进行上报 因为nameserv是无状态的

producer:之间也没有数据的同步 直接启动几个produer就可以 ,和nameserv保持长链接 才可以拿到topic对应的是哪台broker    和master也保持长链接 并且发送心跳
consumer:之间也没有数据的同步 直接启动几个consumer就可以,和nameserv保持长链接 定期从nameserv取topic的路由信息 和master slave也建立长链接 心跳

broker:分主从节点 master slave ,读写分离master负责读写操作(生产者只连接master 消费者连接master和slave) slave负责读操作
				beaker内部有多个组 每个组(brokername相同的为一组)都有master和slave 通过id区分 brokerid为0的是主节点 非0的为slave节点  一个master可对应多个slave 一个slave只能对应一个master, 组内master 通过同步异步 与slave进行消息的同步
 			单master模式:broker宕机服务就不可用 不建议线上使用
 			多master无slave模式: 配置简单
 			多master多slave异步:效率高 prouder发送消息到broker后立即返回结果 broker异步进行刷盘和集群内的消息传递 有可能丢失数据!
 			多master多slave同步:消息安全性高 数据一致性强 丢失数据少(同步传递不会丢失数据!)  但是效率低 produer发送到broker后需要等broker同步得刷盘以及传递消息到其他组内broker进行消息同步完成后才返回给producer
 			broker收到消息后会自动进行持久化!

mqadmin进行集群管理

topic相关	集群相关 消息相关 消费者相关 连接相关 nameserv相关
也可以用rocketmq console

消息的发送

业务分类的标示:topic(1级) tag(2级)     发送到 对应broker的messagequeue

 1)同步消息:生产者发送完后会进行阻塞 直到等到mq返回一个接受的结果才会继续执行      很可靠 用在发送重要的消息 短信通知等  (可以持久化 消费者后开启也能接受到)
 发送的消息包括: topic  tag 内容
 2)异步消息:消息发送后不等待消息回传结果 效率高 可靠性不高  可以指定回掉函数(不能持久化 必须消费者在线的时候发送消息才能接受得到)
 3)单向消息:不关心发送结果的情况下 e.g.日志发送

broker是有多个队列的(为了提高效率) 消息发送过去后broker通过轮训方式依次放到队列当中

顺序消息:(保证的是针对当个生产者所发生的内容顺序是一致的 不保证全局的生产者之间发送的消息的顺序!)
	分区顺序:一个Partition(其实就是messagequeue)内所有的消息按照先进先出的顺序进行发布和消费
	全局顺序:一个Topic内(包含了多个messagequeue)所有的消息按照先进先出的顺序进行发布和消费
	消费者消费消息的顺序要和生产者生产消息的顺序是一致的,如何在前提条件下满足顺序性呢:保证同一个业务的消息发送到同一个队列当中即可(可以通过业务id对队列的size进行取模 来得到一个队列的index 消费者用messagelistenerorderly进行顺序消费即可 可以保证一个线程顺序消费一个业务id标示的message)!消费的时候采用一个线程去取这个队列的消息

延时消息:目前最多延迟两小时进行消费!发送者发送完后立即存储在队列里面 等延迟时间到了后消费者才进行消费

批量消息:发送者一次性发送消息的集合 sned方法发送的不再是message 而是message的list 发送的消息集合一次最好不超过4M 否则要进行消息的分割: 可以使用迭代器借口Iterator进行分割 每次next取出的是大小不超过4M的集合

过滤消息:消息发送到broker后 消费者可以根据某些条件对消息进行过滤
	1)消息消费的以后可以根据tag进行过滤
	2)可以通过设置某个属性的值 消费的时候拿出这个值 根据这个值的范围进行消费 ,支持sql语句和条件判断

事物消息:生产者产生的消息发送给broker是需要经过事物的提交的 否则不能被消费
		发送的是半消息 到达broker后消费者是暂时不可见的
		broker确认收到后调用回调函数让 producer执行一个本地的事务,commit的话提交后broker的消息就能被消费者看到进行被消费 rollback的话 broker就会把消息删除掉
		如果本地事务处理出问题了没有发出commit或者rollback broker会进行回调函数的回查 让本地事物重新commit或者rollback
		(半队列消息会有堆积的情况 所以控制在15次以内 , 不支持延迟消息和批量消息 可能会多次消费)

消息的接受

有两种方式 可以让broker推  也可以consumer去拉

1)负载均衡消费:每个消费者消费其中一部分消息 一起加起来消费完全部的消息 (默认)
2)广播模式消费:消费者每一个都消费相同的全部消息

消息存储

mq是有自动持久化机制的 
activemq默认使用关系型数据库存储 
rocketmq kafka rabbitmq默认都是直接存储到文件系统中 性能>关系型数据库
rocketmq :使用顺序写  零拷贝(NETTY也是 不需要经过用户态 文件大小1G 用于传输)

几个文件:
commitlog:
	所有发送到rocketmq的消息都会存储到commitlog文件中,文件大小就是1个G,存储message queueid 和 topic  consumerqueue,存满一个再来一个G,顺序写, 读是加了索引的 通过consumerqueue作为索引获得所要查的消息的位置才去commitlog精准定位位置,加快commitlog读取速度,一个messagequeue消息队列就对应一个cosummerqueue(读取到内存中)作为索引
indexfile:同样是索引文件 区别于consumerqueue的方式,通过keys(消息关键字)和时间区间来查询消息

在这里插入图片描述
在这里插入图片描述
刷盘机制

消息先写到内存pagecache当中 然后再通知刷盘线程写到磁盘中去 
同步刷盘:
刷盘线程完成后才唤醒线程然后对生产者进行反馈 可靠性高 一定是刷盘成功后才返回的

异步刷盘:
写到pagecache后直接对生产者进行响应 然后开启另外一个线程进行刷盘 效率高 但是不一定刷盘成功会有数据丢失的危险

rocketmq的高可用性

 除了上述的集群配置之外 从消费的角度来说:
 consumer消费的时候先从master进行消费 master无法消费(不可用或者繁忙)的时候就会自动切换到slave去 
 producer可以向多个master进行写入 挂掉一个写另外一个来保证高可用 所以在发送消息的时候要指多个broker来保证高可用

主从复制

同步复制 :安全 吞吐量高低 
异步复制:数据可能会丢失 吞度量高 

一般配置异步刷盘保证吞吐量 同步主从复制保证消息的不丢失

负载均衡

producer:
轮训的策略 因为topic可以绑定不同的broker 也因为broker里面有多个队列 首先是给broker里面不同的队列进行发送 然后再跨broker进行发送来进行轮训发送

consumer:
集群模式:
多个消费者共同完成他们对应的topic下所有队列的消费 均摊 启动多个消费者即可 因为是无状态和 和nameserv和producer一样 
  两种方式 1 均摊负载均衡同一个broker里面的不同queue
  				  2 均摊负载均衡不跨broker里面的queue
  	要让队列queue的数量 > 消费者的数量    这样每个消费者才可以工作 因为如果负载均衡的消费者已经够了 多余的不会进行工作!
广播模式:
每个消费者全部消费一遍queue   其实这种模式就不算是负载均衡了!

消息重试

为了保证消息一定会被消费掉

顺序消息:
自动就保证一定会消息重试 在消息没有被消费者反馈的时候  而且前面的消费者如果没有消费完毕 为了保证顺序性 后面的消费者不可以进行消费 所以有可能导致消费的阻塞 需要在使用顺序消息的时候监控好 避免产生生产情况下的阻塞

除了顺序消息之外的无序消息:
	只对集群负载均衡消息有效  对广播消息无效 也就是广播消息不管成功还是失败只能消费一次!
	默认允许重复消费16次(4小时46分钟 大于16的每次2小时) 超过之后还没有消费到的话就会进入死信队列
	触发重试的机制:
		返回ACtion.ReconsumeLater;  null 或者抛出异常都会进行重试!
		如果希望不进行重试 就在catch或者外部进行 return Action.commitmessage
	可以对同一个组(groupid)下的consumer设置最大重试次数
	后启动的consumer的配置会覆盖前面的配置
	

死信队列

超过重试次数的会被放入死信队列
	死信队列中的消息:
		不会再被消费者正常消费
		3天后删除(和正常的消息一样) 所以要在3天内处理死信队列的消息
		一个死信队列面向同一个groupid(消费者组)
处理方法:
	可以让消息重新消费一次,也可以针对死信队列的消息进行消费

消息幂等姓
在这里插入图片描述

1通过消息id保证    但是rockatmq不保证消息id唯一
2使用业务标示 业务key, 在消费方存储key 然后每次请求的时候去查询是否存在这个key    ,  message.setKey
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值