# Service Scenario

Let’s take the order function as an example: the order will be automatically closed if it is not paid for a period of time after the order is generated. The simplest idea is to set the scheduled task polling, but the creation time of each order is different, and the rule of scheduled task cannot be set. If the interval of scheduled task execution is set too short, the efficiency will be affected. There is also the idea of timing the action when the user enters the order interface. This can be done in many ways, but here is a way to monitor the expiration time of the Redis key-value pair to automatically close the order. Put together a full version of the Java Interview guide PDF

# Implementation ideas

When generating an order, add a KV key value pair to Redis, where K is the order number, and ensure that an order in the database can be located through K, and V can be any value. Suppose, when generating an order, K is stored in Redis as the order number, V is also the key value pair of the order number, and the expiration time is set to 30 minutes. If the key value pair can send a notice to the program or execute a method after the expiration time of 30 minutes, then the order closing problem can be solved. Implementation: This is achieved by listening on the expiration queue provided by Redis. After listening on the expiration queue, if a KV key pair in Redis has expired, a message will be sent to the listener, and the listener can obtain K of the key pair. Note that V cannot be obtained because it has expired, which is mentioned above. Why is it necessary to ensure that the order can be located by K, while V is any value? After getting K, locate the order through K and judge its status. If it is unpaid, update it to close or cancel the status.

# Enable Redis key expiration reminder

Modify the configurations of events related to Redis. Find the redis configuration file redis.conf and check the notify-keyspace-events configuration item. If it does not exist, add the notify-keyspace-events Ex.

  • K: Keyspace event. The event is advertised with keyspace@ as the prefix

  • E: Keyevent event. The event is published with the prefix keyevent@

  • G: generic, non-specific commands, such as del, expire, rename, etc

  • $: string specific command

  • L: Lists specific commands

  • S: sets specific commands

  • H: Hashes specific commands

  • Z: An ordered set of specific commands

  • X: Expiration event, which is generated when a key expires and is deleted

  • E: Expulsion event, which occurs when a key is deleted due to the Maxmemore policy

  • A: Alias for g$lshzxe, so “AKE” means all events

# Introduce dependencies

In pom. Add org XML. Springframework. The boot: spring – the boot – starter – data – redis dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Copy the code

# Related configuration

Configure RedisListenerConfig to monitor the expiration time of the Redis key

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.RedisMessageListenerContainer; @Configuration public class RedisListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); return container; }}Copy the code

Define listener RedisKeyExpirationListener, realize KeyExpirationEventMessageListener interface, view the source code, Keyevent @*:expired” this interface listens for expired events in all dB files

import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.stereotype.Component; / * * * to monitor all the db expired events __keyevent @ * __ : expired "* / @ Component public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener { public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {  super(listenerContainer); } /** * For redis data failure event, * @param message * @param pattern */ @override public void onMessage(message message, Byte [] pattern) {// Obtain the invalid key and cancel the order. String expiredKey = message.toString(); System.out.println(expiredKey); }}Copy the code