目录

mq思考

mq技术思考

为什么要使用某个技术,解决什么问题,适合的场景,调研,优缺点是什么,各个同类型技术的对比[!技术选型!]

mq解决什么问题

mq解决什么问题:解耦,异步(削峰:[5000/s请求,mysql一般扛2000/s请求])

互联网公司,每个用户请求必须要求在[200ms]以内,用户才会无感知,体验比较好

需要[清楚]每个请求,后台做了哪些事情,[具体耗费时间在哪里],比如sql50ms,调B服务300ms,调C服务400ms,是否可以架构优化,引入mq

了解线上多少用户,系统一定会有[高峰,低峰],多少tps(峰值,低谷),mysql崩溃系统就崩溃

引入mq缺点/问题

  1. 可用性降低:本来考虑几个系统,现在再考虑mq不能挂,一挂就可能全面瘫痪
  2. 复杂性变高:一条消息重复发送,消息丢失,消息顺序乱了,mq磁盘满没有消费
  3. 一致性问题:A→MQ→B/C,AB成功,C失败,后台逻辑没完全执行完

技术选型

activemq:万级,早期公司会用,社区不够活跃

rabbitmq:万级,中小型公司用的多,erlang高性能,社区活跃

rocketmq:十万级,中大型公司,阿里开源,高吞吐场景验证,阿里有可能以后放弃该项目

kafka:十万级,大数据领域,日志采集,业界标杆

保证mq高可用

rabbitmq(非分布式-一个queue数据放在一个节点上)

  1. 普通集群模式,一个节点包含queue元数据和实际数据,其他节点只包含元数据,消费节点间需要网络传输,非高可用
  2. 镜像集群模式,每个rabbitmq节点包含queue的全部数据,消费某个节点即可,高可用

kafka(分布式-一个topic数据可以分patition)

一个topic,分3个patition在3台机器的3个broker内,所以是分布式的;每个broker会有一个副本,主从,一个leader(读写入口),一个follower;从leader读写,必须所有follower都读写成功返回ack标示,才会返回给调用方

消息重复消费问题预案

场景:kafka消费者定期将offset写到zookeeper,kafka读取推送offset之后的消息,如果offset写到zk前应用重启,有可能重复消费

方案:幂等性校验,比如mq内容带id,消费前判断id是否落库,绑卡成功送积分,判断卡号/流水不重复不能重复送积分

消息可靠性传输不丢失

rabbitmq

  1. 生产者丢失(网络传输问题):第一种采用事务,同步等待性能低下;第二种confirm机制,异步回调ack(msgId)或者nack(msgId),一般采用这种,性能较高
  2. rabbitmq丢失(存在内存中,挂了重启内存中消失):配置落磁盘
  3. 消费者丢失(没消费完,autoAck通知处理完,挂了):关闭autoAck,消费完自己发送ack到rabbitmq,中途异常配合幂等性即可

消息顺序错乱

新增,删除→删除,新增,结果就完全不一样

一个queue,多个consumer消费,顺序错乱;

要保证一致性,只能一个queue一个consumer去消费;

但是吞度量比较小,可以根据保证顺序的id来hash进入多个内存queue,多线程指向内存queue消费

超时失效,积压几个小时,上千万消息,消息磁盘满了,怎么办

[上千万消息]-临时扩容:kafka一个topic,3个patition,3个消费者,消费1小时;修改消费者代码,接受消息马上向另一个topic写(30个patition,30个消费者),消费6分钟结束!

[超时失效]:找源头,手动发mq然后补单消费

[消息磁盘满了]:临时搭一个mq,修改消费者代码,消费马上发到新mq,慢慢消费,把这台mq量减下来;或者消费完直接丢弃,晚上写代码,从源头自己手动发mq然后补单消费

如何设计一个mq

  1. 支持落磁盘
  2. 扩展性,分布式参考kafka,一个topic分多个patition落在不同机器的broker上
  3. 高可用,kafka副本,rabbitmq镜像拷贝
  4. 0丢失,参考rabbitmq的confirm机制,落磁盘,手动ack