Usage scenarios

1, checkout success ,30 Minutes unpaid . Payment overtime , Automatic order cancellation

2, Order signing , After signing 7 There was no evaluation in the past three days . Order timeout not evaluated , System default praise

3, checkout success , business 5 No orders received in 15 minutes , Order cancellation

4, Delivery timeout , Push SMS reminder

......

For the scene with long delay , Scenes with low real-time performance , We can use the way of task scheduling to polling regularly . as :xxl-job

Today, we adopt a relatively simple method , Lightweight way , use Redis
Delay queue for processing . Of course, there is a better solution , According to the company's technology selection and business system to choose the best solution . as : Using message oriented middleware Kafka,RabbitMQ  Delay queue for

The implementation principle is not discussed , Direct combat on the code first based on Redis Delay queue for

1, introduce Redisson rely on
<dependency> <groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId> <version>3.10.5</version>
</dependency>
2,Nacos to configure  Redis connect
spring: redis: host: 127.0.0.1 port: 6379 password: 123456 database: 12
timeout: 3000
3, establish RedissonConfig to configure
/** * Created by LPB on 2020/04/20. */ @Configuration public class
RedissonConfig { @Value("${spring.redis.host}") private String host;
@Value("${spring.redis.port}") private int port;
@Value("${spring.redis.database}") private int database;
@Value("${spring.redis.password}") private String password; @Bean public
RedissonClient redissonClient() { Config config = new Config();
config.useSingleServer() .setAddress("redis://" + host + ":" + port)
.setDatabase(database) .setPassword(password); return Redisson.create(config);
} }
4, encapsulation Redis Delay queue tool class
/** * redis Delay queue tool * Created by LPB on 2021/04/20. */ @Slf4j @Component public
class RedisDelayQueueUtil { @Autowired private RedissonClient redissonClient;
/** * Add delay queue * @param value Queue value * @param delay delay time * @param timeUnit Time unit *
@param queueCode Queue key * @param <T> */ public <T> void addDelayQueue(T value,
long delay, TimeUnit timeUnit, String queueCode){ try { RBlockingDeque<Object>
blockingDeque = redissonClient.getBlockingDeque(queueCode);
RDelayedQueue<Object> delayedQueue =
redissonClient.getDelayedQueue(blockingDeque); delayedQueue.offer(value, delay,
timeUnit); log.info("( Add delay queue successfully ) Queue key :{}, Queue value :{}, delay time :{}", queueCode, value,
timeUnit.toSeconds(delay) + " second "); } catch (Exception e) { log.error("( Failed to add delay queue )
{}", e.getMessage()); throw new RuntimeException("( Failed to add delay queue )"); } } /** *
Get delay queue * @param queueCode * @param <T> * @return * @throws InterruptedException
*/ public <T> T getDelayQueue(String queueCode) throws InterruptedException {
RBlockingDeque<Map> blockingDeque = redissonClient.getBlockingDeque(queueCode);
T value = (T) blockingDeque.take(); return value; } }
5, Create delay queue service enumeration
/** * Delay queue service enumeration * Created by LPB on 2021/04/20. */ @Getter @NoArgsConstructor
@AllArgsConstructor public enum RedisDelayQueueEnum {
ORDER_PAYMENT_TIMEOUT("ORDER_PAYMENT_TIMEOUT"," Order payment timeout , Automatic order cancellation ",
"orderPaymentTimeout"),
ORDER_TIMEOUT_NOT_EVALUATED("ORDER_TIMEOUT_NOT_EVALUATED", " Order timeout not evaluated , System default praise ",
"orderTimeoutNotEvaluated"); /** * Delay queue Redis Key */ private String code; /** *
Chinese description */ private String name; /** * Implementation of delay queue service Bean * Available through Spring Context acquisition for */
private String beanId; }
6, Define delay queue executors
/** * Delay queue actuator * Created by LPB on 2021/04/20. */ public interface
RedisDelayQueueHandle<T> { void execute(T t); }
7, Create the Bean, And implement delay queue executor

* OrderPaymentTimeout: Order payment timeout delay queue processing class /** * Order payment overtime processing class * Created by LPB on
2021/04/20. */ @Component @Slf4j public class OrderPaymentTimeout implements
RedisDelayQueueHandle<Map> { @Override public void execute(Map map) {
log.info("( Receive order payment timeout delay message ) {}", map); // TODO Order payment timeout , Automatic order cancellation ... } }
* OrderTimeoutNotEvaluated: Order timeout not evaluated delay queue processing class /** * Order timeout not evaluated processing class * Created by LPB
on 2021/04/20. */ @Component @Slf4j public class OrderTimeoutNotEvaluated
implements RedisDelayQueueHandle<Map> { @Override public void execute(Map map)
{ log.info("( Received order timeout not evaluated delay message ) {}", map); // TODO Order timeout not evaluated , The system processes business by default ... } }
8, Create delay queue consumption thread , Start after the project is started
/** * Start delay queue * Created by LPB on 2021/04/20. */ @Slf4j @Component public class
RedisDelayQueueRunner implements CommandLineRunner { @Autowired private
RedisDelayQueueUtil redisDelayQueueUtil; @Override public void run(String...
args) { new Thread(() -> { while (true){ try { RedisDelayQueueEnum[] queueEnums
= RedisDelayQueueEnum.values(); for (RedisDelayQueueEnum queueEnum :
queueEnums) { Object value =
redisDelayQueueUtil.getDelayQueue(queueEnum.getCode()); if (value != null) {
RedisDelayQueueHandle redisDelayQueueHandle =
SpringUtil.getBean(queueEnum.getBeanId());
redisDelayQueueHandle.execute(value); } } } catch (InterruptedException e) {
log.error("(Redis Delay queue interrupt ) {}", e.getMessage()); } } }).start();
log.info("(Redis Delay queue started successfully )"); } }
The above steps ,Redis Delay queue core code is complete , Let's write a test interface , use PostMan Do a simulation test

 

9, Create a test interface , Simulate adding delay queue
/** * Delay queue test * Created by LPB on 2020/04/20. */ @RestController public class
RedisDelayQueueController { @Autowired private RedisDelayQueueUtil
redisDelayQueueUtil; @PostMapping("/addQueue") public void addQueue() {
Map<String, String> map1 = new HashMap<>(); map1.put("orderId", "100");
map1.put("remark", " Order payment timeout , Automatic order cancellation "); Map<String, String> map2 = new
HashMap<>(); map2.put("orderId", "200"); map2.put("remark", " Order timeout not evaluated , System default praise ");
// Add order payment timeout , Automatic order cancellation delay queue . In order to test the effect , delay 10 second redisDelayQueueUtil.addDelayQueue(map1,
10, TimeUnit.SECONDS, RedisDelayQueueEnum.ORDER_PAYMENT_TIMEOUT.getCode()); //
Order timeout not evaluated , System default praise . In order to test the effect , delay 20 second redisDelayQueueUtil.addDelayQueue(map2, 20,
TimeUnit.SECONDS, RedisDelayQueueEnum.ORDER_TIMEOUT_NOT_EVALUATED.getCode()); }
}
10, start-up SpringBoot project , use PostMan Call interface to add delay queue

* adopt Redis The client can see that two delay queues have been added successfully

* see IDEA The console log shows that the delay queue has been consumed successfully

 

Technology
©2020 ioDraw All rights reserved
0.96OLED display -4 Line SPI explain C++11 of std::function,std::bind,std::placeholdersJavaScript study ( Function declaration and parameters )QTabWidget Style sheet settings The project passed idea Package and publish to tomcat The server postman Interface test get timestamp and MD5 encryption react Background management configuration route and sidebar :python Simple game code -10 Minutes Python Write a snake game , simple You know? Python What does the foundation include ? Learn something ?10 individual Python Introduction to crawler