上一篇
"小王啊,用户下单15分钟未支付要自动取消订单" "小李,促销活动开始前要给VIP用户提前10分钟发提醒" "老张,这个工单超过48小时没处理要自动升级..."
产品经理的"定时炸弹"需求是不是听得耳朵起茧?🤯 别急,今天咱们就来彻底解决这个分布式系统中的"定时难题"!
// 伪代码示例 while(true) { List<Message> messages = query("SELECT * FROM delay_queue WHERE execute_time <= NOW()"); for(Message msg : messages) { process(msg); delete(msg); } sleep(5_000); // 5秒轮询一次 }
优点:实现简单,小学生都能看懂
缺点:数据库压力大,延迟高(最坏情况要等5秒)
适用场景:小规模应用,对实时性要求不高
DelayQueue<DelayedTask> queue = new DelayQueue<>(); // 添加任务 queue.put(new DelayedTask("订单取消", 15, TimeUnit.MINUTES)); // 消费任务 while(true) { DelayedTask task = queue.take(); task.execute(); }
优点:精度高,Java原生支持
缺点:内存限制,重启丢数据,不能分布式
适用场景:单机定时任务管理
# 设置消息TTL为15分钟 x-dead-letter-exchange: your_exchange x-dead-letter-routing-key: your_routing_key
优点:利用成熟中间件,可靠性高
缺点:配置复杂,时间精度受限
// 发送延迟消息 Message message = new Message("Topic", "Tag", "订单取消".getBytes()); message.setDelayTimeLevel(3); // 对应10s延迟 producer.send(message);
优点:开箱即用,性能好
缺点:只支持固定延迟等级(1s/5s/10s/30s/1m...)
// 使用Kafka+Redis实现 val delayedTopics = Map( "15min" -> "order_cancel", "1h" -> "coupon_expire" )
优点:可扩展性强
缺点:实现复杂,需要自己造轮子
Netty的HashedWheelTimer原理:
// 创建时间轮 Timer timer = new HashedWheelTimer( threadFactory, 100, // 1个tick=100ms TimeUnit.MILLISECONDS, 512 // 轮子大小 ); // 添加延迟任务 timer.newTimeout(task, 15, TimeUnit.MINUTES);
优点:O(1)时间复杂度,性能炸裂
缺点:单机内存限制,需要自己实现分布式
综合各派所长,2025年最推荐的架构方案:
[生产者] --> [Kafka/RocketMQ]
--> [延时队列服务]
--> [Redis Sorted Set]
--> [处理Worker]
关键实现步骤:
# 伪代码示例 def process_delay_message(): while True: now = time.time() # 获取所有score<=now的消息 messages = redis.zrangebyscore("delay_queue", 0, now) for msg in messages: if redis.zrem("delay_queue", msg): # 原子操作防重复 send_to_worker(msg) time.sleep(0.1) # 100ms精度
当产品经理又提出"要支持精确到毫秒的亿级延迟消息"时,记得反问:
下次再有人问分布式延迟消息怎么实现?直接把这篇文章甩给他! 📨 记得收藏,防身必备!
本文由 栗雅安 于2025-08-10发表在【云服务器提供商】,文中图片由(栗雅安)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://up.7tqx.com/wenda/581235.html
发表评论