【Netty源码解读和权威指南】第36篇:Netty时间轮高级应用——10亿级定时任务的工程实践

【Netty源码解读和权威指南】第36篇:Netty时间轮高级应用——10亿级定时任务的工程实践

上一篇【第35篇】Netty时间轮HashedWheelTimer源码解析——百万定时任务的秘密
下一篇【第37篇】Netty流量整形——优雅控制客户端发送速率


一、场景一:延迟消息队列

publicclassDelayMessageQueue{privatefinalHashedWheelTimertimer=newHashedWheelTimer();privatefinalMap<String,Timeout>pending=newConcurrentHashMap<>();// 发送延迟消息publicvoidsendDelayed(StringmsgId,Stringcontent,longdelayMs){Timeouttimeout=timer.newTimeout(t->{pending.remove(msgId);System.out.println("延迟消息到达: id="+msgId+", content="+content);processMessage(content);},delayMs,TimeUnit.MILLISECONDS);pending.put(msgId,timeout);}// 取消延迟消息publicvoidcancelDelayed(StringmsgId){Timeouttimeout=pending.remove(msgId);if(timeout!=null)timeout.cancel();}}

二、场景二:超时重试

publicclassTimeoutRetryHandler{privatefinalHashedWheelTimertimer=newHashedWheelTimer();publicFuture<?>sendWithRetry(Channelchannel,Objectmsg,intmaxRetries){Promise<Boolean>promise=channel.eventLoop().newPromise();doSend(channel,msg,promise,maxRetries,0);returnpromise;}privatevoiddoSend(Channelchannel,Objectmsg,Promise<Boolean>promise,intmaxRetries,intattempt){channel.writeAndFlush(msg).addListener(f->{if(f.isSuccess()){promise.setSuccess(true);}elseif(attempt<maxRetries){// 指数退避:1s, 2s, 4s, 8s...longdelay=(long)Math.pow(2,attempt)*1000;timer.newTimeout(t->doSend(channel,msg,promise,maxRetries,attempt+1),delay,TimeUnit.MILLISECONDS);}else{promise.setFailure(f.cause());}});}}

三、场景三:连接心跳管理

publicclassHeartbeatManager{privatefinalHashedWheelTimertimer=newHashedWheelTimer();privatefinalMap<Channel,Timeout>heartbeats=newConcurrentHashMap<>();publicvoidstartHeartbeat(Channelchannel,longintervalMs){scheduleHeartbeat(channel,intervalMs);}privatevoidscheduleHeartbeat(Channelchannel,longintervalMs){Timeouttimeout=timer.newTimeout(t->{if(channel.isActive()){channel.writeAndFlush(newHeartbeatMsg());scheduleHeartbeat(channel,intervalMs);// 递归调度}},intervalMs,TimeUnit.MILLISECONDS);heartbeats.put(channel,timeout);}publicvoidstopHeartbeat(Channelchannel){Timeouttimeout=heartbeats.remove(channel);if(timeout!=null)timeout.cancel();}}

四、大规模定时任务:层级时间轮设计

单层时间轮8槽×100ms = 800ms周期。如果需要1小时的定时任务,就需要大量remainingRounds。

层级时间轮:多层时间轮,每层精度不同。

Layer 0: 256槽 × 1ms = 256ms (毫秒级) Layer 1: 64槽 × 256ms = 16.384s (秒级) Layer 2: 64槽 × 16s = 1024s (分钟级) Layer 3: 64槽 × 17min = 18小时 (小时级) 当Layer 0转满一轮,Layer 1推进一格 当Layer 1转满一轮,Layer 2推进一格

五、总结

场景实现方式优势
延迟消息timer.newTimeout()O(1)插入
超时重试递归调度+指数退避自动重试
心跳管理递归调度心跳任务无需线程池
大规模任务层级时间轮亿级定时任务

上一篇【第35篇】Netty时间轮HashedWheelTimer源码解析——百万定时任务的秘密
下一篇【第37篇】Netty流量整形——优雅控制客户端发送速率