消息队列设计
关于消息队列
MQ 是现代微服务架构和云原生架构的基础服务组件,主要用来做异步处理、服务解耦、流量削峰等。一个高性能、低延迟、高可用、高可靠的消息队列在互联网业务中是非常必要的。
常见的 MQ:
资源参考
bigqueue A big, fast and persistent queue based on memory mapped file.
killbill-commons/queue Notification Queue: persistent job queue, used for jobs scheduling
消息队列性能分析 chrome-extension://ikhdkkncnoglghljlkmcimlnlhkeamad/pdf-viewer/web/viewer.html?file=https%3A%2F%2Fdigitalscholarship.unlv.edu%2Fcgi%2Fviewcontent.cgi%3Farticle%3D4749%26context%3Dthesesdissertations https://digitalscholarship.unlv.edu/cgi/viewcontent.cgi?article=4749&context=thesesdissertations
博客
Big Queue
一个基于内存映射文件的大型、快速且持久的队列。
应用场景
大数据场景下的日志收集
大数据场景下的排序和搜索
作为分布式消息队列的基础组件
前置知识
什么是 Memory-Mapped file?(内存映射文件原理探索,认真分析mmap,图文详解内存映射)
数据结构:队列
In message-oriented middleware solutions, fan-out is a messaging pattern used to model an information exchange that implies the delivery (or spreading) of a message to one or multiple destinations possibly in parallel, and not halting the process that executes the messaging to wait for any response to that message
设计
整体架构设计(模型) / 接口设计 / 使用和实现
Messaging
内存队列
JUC ArrayBlockingQueue
JUC PriorityBlockingQueue
The LAMX Architecture by Martin Fowler, 中文版翻译
Introduction to the Disruptor
延迟队列
延迟队列的主要特性是进入队列的消息会被推迟到指定的时间才出队被消费。
延迟队列的一个实现:delay-queue, 参考了有赞的延迟队列设计
JUC 延迟队列实现:DelayQueue, 实现思路是 lock + 优先级队列, (Leader/Follower 模式), 并发模式
延迟队列场景:
订单在30分钟之内未支付则自动取消。
重试机制实现,把调用失败的接口放入一个固定延时的队列,到期后再重试。
新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。
用户发起退款,如果三天内没有得到处理则通知相关运营人员。
预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议。
关闭空闲连接,服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之。
清理过期数据业务。比如缓存中的对象,超过了空闲时间,需要从缓存中移出。
多考生考试,到期全部考生必须交卷,要求时间非常准确的场景。
解决方案:
定期轮询(数据库等)
JDK DelayQueue
JDK Timer
ScheduledExecutorService 周期性线程池
时间轮(kafka)
时间轮(Netty的HashedWheelTimer)
Redis有序集合(zset)
zookeeper之curator
RabbitMQ
Quartz,xxljob等定时任务框架
Koala(考拉)
JCronTab(仿crontab的java调度器)
SchedulerX(阿里)
有赞延迟队列
时间轮算法
如果一个系统中存在着大量的调度任务,而大量的调度任务如果每一个都使用自己的调度器来管理任务的生命周期的话,浪费cpu的资源并且很低效。
时间轮是一种高效来利用线程资源来进行批量化调度的一种调度模型。把大批量的调度任务全部都绑定到同一个的调度器上面,使用这一个调度器来进行所有任务的管理(manager),触发(trigger)以及运行(runnable)。能够高效的管理各种延时任务,周期任务,通知任务等等。
不过,时间轮调度器的时间精度可能不是很高,对于精度要求特别高的调度任务可能不太适合。因为时间轮算法的精度取决于,时间段“指针”单元的最小粒度大小,比如时间轮的格子是一秒跳一次,那么调度精度小于一秒的任务就无法被时间轮所调度。
最后更新于