From da1f25f4c190e4504c786b1992f34effe7233865 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E6=9F=922012?= <345849402@qq.com>
Date: Mon, 10 Feb 2020 20:40:52 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=E5=9F=BA=E4=BA=8E=20netty=20?=
=?UTF-8?q?=E7=9A=84=E6=97=B6=E9=97=B4=E8=BD=AE=E7=AE=97=E6=B3=95=20Hashed?=
=?UTF-8?q?WheelTimer=20=E5=AE=9E=E7=8E=B0=E7=9A=84=E5=BB=B6=E8=BF=9F?=
=?UTF-8?q?=E4=BB=BB=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 11 ++++++
.../delay/{ => jvm}/RedPacketDelayQueue.java | 11 +++---
.../delay/jvm}/RedPacketMessage.java | 2 +-
.../queue/delay/jvm/RedPacketQueue.java | 2 --
.../seckill/queue/delay/jvm/TaskRunner.java | 1 -
.../netty/RedPacketHashedWheelTimer.java | 35 +++++++++++++++++++
.../queue/delay/netty/RedPacketTimerTask.java | 35 +++++++++++++++++++
.../seckill/web/RedPacketController.java | 2 +-
8 files changed, 87 insertions(+), 12 deletions(-)
rename src/main/java/com/itstyle/seckill/queue/delay/{ => jvm}/RedPacketDelayQueue.java (85%)
rename src/main/java/com/itstyle/seckill/{common/entity => queue/delay/jvm}/RedPacketMessage.java (98%)
create mode 100644 src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketHashedWheelTimer.java
create mode 100644 src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketTimerTask.java
diff --git a/pom.xml b/pom.xml
index 4094580..ab9c109 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,6 +136,17 @@
sentinel-core
1.6.3
+
+ org.projectlombok
+ lombok
+ 1.18.8
+ provided
+
+
+ io.netty
+ netty-common
+ 4.1.23.Final
+
spring-boot-seckill
diff --git a/src/main/java/com/itstyle/seckill/queue/delay/RedPacketDelayQueue.java b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketDelayQueue.java
similarity index 85%
rename from src/main/java/com/itstyle/seckill/queue/delay/RedPacketDelayQueue.java
rename to src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketDelayQueue.java
index 181745f..b9d83ab 100644
--- a/src/main/java/com/itstyle/seckill/queue/delay/RedPacketDelayQueue.java
+++ b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketDelayQueue.java
@@ -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;
/**
* 红包过期失效 延迟队列
diff --git a/src/main/java/com/itstyle/seckill/common/entity/RedPacketMessage.java b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketMessage.java
similarity index 98%
rename from src/main/java/com/itstyle/seckill/common/entity/RedPacketMessage.java
rename to src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketMessage.java
index 0c2216c..8257729 100644
--- a/src/main/java/com/itstyle/seckill/common/entity/RedPacketMessage.java
+++ b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketMessage.java
@@ -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;
diff --git a/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketQueue.java b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketQueue.java
index bd196a7..4c84f98 100644
--- a/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketQueue.java
+++ b/src/main/java/com/itstyle/seckill/queue/delay/jvm/RedPacketQueue.java
@@ -1,7 +1,5 @@
package com.itstyle.seckill.queue.delay.jvm;
-import com.itstyle.seckill.common.entity.RedPacketMessage;
-
import java.util.concurrent.DelayQueue;
/**
diff --git a/src/main/java/com/itstyle/seckill/queue/delay/jvm/TaskRunner.java b/src/main/java/com/itstyle/seckill/queue/delay/jvm/TaskRunner.java
index 6f63774..65ff42d 100644
--- a/src/main/java/com/itstyle/seckill/queue/delay/jvm/TaskRunner.java
+++ b/src/main/java/com/itstyle/seckill/queue/delay/jvm/TaskRunner.java
@@ -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;
diff --git a/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketHashedWheelTimer.java b/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketHashedWheelTimer.java
new file mode 100644
index 0000000..eef9e60
--- /dev/null
+++ b/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketHashedWheelTimer.java
@@ -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);
+ }
+}
diff --git a/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketTimerTask.java b/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketTimerTask.java
new file mode 100644
index 0000000..f3c12d3
--- /dev/null
+++ b/src/main/java/com/itstyle/seckill/queue/delay/netty/RedPacketTimerTask.java
@@ -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));
+ }
+}
diff --git a/src/main/java/com/itstyle/seckill/web/RedPacketController.java b/src/main/java/com/itstyle/seckill/web/RedPacketController.java
index ece9499..e5111cb 100644
--- a/src/main/java/com/itstyle/seckill/web/RedPacketController.java
+++ b/src/main/java/com/itstyle/seckill/web/RedPacketController.java
@@ -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;