:sparkles:基于 netty 的时间轮算法 HashedWheelTimer 实现的延迟任务

This commit is contained in:
小柒2012
2020-02-10 20:40:52 +08:00
parent eaa8c027a9
commit da1f25f4c1
8 changed files with 87 additions and 12 deletions

11
pom.xml
View File

@@ -136,6 +136,17 @@
<artifactId>sentinel-core</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>4.1.23.Final</version>
</dependency>
</dependencies>
<build>
<finalName>spring-boot-seckill</finalName>

View File

@@ -1,14 +1,11 @@
package com.itstyle.seckill.queue.delay;
package com.itstyle.seckill.queue.delay.jvm;
import com.itstyle.seckill.common.entity.RedPacketMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 红包过期失效 延迟队列

View File

@@ -1,4 +1,4 @@
package com.itstyle.seckill.common.entity;
package com.itstyle.seckill.queue.delay.jvm;
import java.time.Instant;
import java.time.LocalDateTime;

View File

@@ -1,7 +1,5 @@
package com.itstyle.seckill.queue.delay.jvm;
import com.itstyle.seckill.common.entity.RedPacketMessage;
import java.util.concurrent.DelayQueue;
/**

View File

@@ -1,6 +1,5 @@
package com.itstyle.seckill.queue.delay.jvm;
import com.itstyle.seckill.common.entity.RedPacketMessage;
import com.itstyle.seckill.common.redis.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@@ -0,0 +1,35 @@
package com.itstyle.seckill.queue.delay.netty;
import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
import io.netty.util.TimerTask;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
/**
* 基于 netty 的时间轮算法 HashedWheelTimer 实现的延迟任务
*/
public class RedPacketHashedWheelTimer {
public static void main(String[] args) throws Exception {
ThreadFactory factory = r -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
thread.setName("RedPacketHashedWheelTimerWorker");
return thread;
};
/**
* @param tickDuration - 每tick一次的时间间隔
* @param unit - tickDuration 的时间单位
* @param ticksPerWheel - 时间轮中的个数
*/
Timer timer = new HashedWheelTimer(factory, 1,
TimeUnit.SECONDS, 100);
for(int i=0;i<100;i++){
TimerTask timerTask = new RedPacketTimerTask(i);
timer.newTimeout(timerTask, i, TimeUnit.SECONDS);
}
Thread.sleep(Integer.MAX_VALUE);
}
}

View File

@@ -0,0 +1,35 @@
package com.itstyle.seckill.queue.delay.netty;
import io.netty.util.Timeout;
import io.netty.util.TimerTask;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class RedPacketTimerTask implements TimerTask {
private static final DateTimeFormatter F = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
/**
* 红包 ID
*/
private final long redPacketId;
/**
* 创建时间戳
*/
private final long timestamp;
public RedPacketTimerTask(long redPacketId) {
this.redPacketId = redPacketId;
this.timestamp = System.currentTimeMillis();
}
@Override
public void run(Timeout timeout) {
System.out.println(String.format("任务执行时间:%s,红包创建时间:%s,红包ID:%s",
LocalDateTime.now().format(F), LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault()).format(F), redPacketId));
}
}

View File

@@ -1,10 +1,10 @@
package com.itstyle.seckill.web;
import com.itstyle.seckill.common.entity.RedPacketMessage;
import com.itstyle.seckill.common.entity.Result;
import com.itstyle.seckill.common.redis.RedisUtil;
import com.itstyle.seckill.common.utils.DoubleUtil;
import com.itstyle.seckill.queue.delay.jvm.RedPacketMessage;
import com.itstyle.seckill.queue.delay.jvm.RedPacketQueue;
import com.itstyle.seckill.service.IRedPacketService;
import io.swagger.annotations.Api;