上一篇【第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流量整形——优雅控制客户端发送速率