To achieve "after the deadline delete" function by subscribing to redis event

Think

Scenario
One such scenario, a system for users to open up a space, this space is free to use in the period. But after the expiration to recover. We can check the presence of spatial information in database tables by the timing task, if the deadline to, a corresponding operation proceeds. This can also throw the timing of projects outside the system.

Another idea
we can try another program, such as creating space when the space id as a key part stored in redis, whereas ex set to the effective time. When this timeout redis key to delete, and inform our system, so as to complete the operation to clear space.

Implement

Specific achieve the following:

1. Open Event

1.1, modify the configuration file

The default redis did not turn on this feature, you need to modify the notify-keyspace-events profile configuration

############################# Event notification ##############################

# Redis can notify Pub/Sub clients about events happening in the key space.
# This feature is documented at http://redis.io/topics/notifications
# 
# For instance if keyspace events notification is enabled, and a client
# performs a DEL operation on key "foo" stored in the Database 0, two
# messages will be published via Pub/Sub:
#
# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo
#
# It is possible to select the events that Redis will notify among a set
# of classes. Every class is identified by a single character:
#
#  K     Keyspace events, published with __keyspace@<db>__ prefix.
#  E     Keyevent events, published with __keyevent@<db>__ prefix.
#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
#  $     String commands
#  l     List commands
#  s     Set commands
#  h     Hash commands
#  z     Sorted set commands
#  x     Expired events (events generated every time a key expires)
#  e     Evicted events (events generated when a key is evicted for maxmemory)
#  A     Alias for g$lshzxe, so that the "AKE" string means all the events.
#
#  The "notify-keyspace-events" takes as argument a string that is composed
#  by zero or multiple characters. The empty string means that notifications
#  are disabled at all.
#
#  Example: to enable list and generic events, from the point of view of the
#           event name, use:
#
#  notify-keyspace-events Elg
#
#  Example 2: to get the stream of the expired keys subscribing to channel
#             name __keyevent@0__:expired use:
#
#  notify-keyspace-events Ex
#
#  By default all notifications are disabled because most users don't need
#  this feature and the feature has some overhead. Note that if you don't
#  specify at least one of K or E, no events will be delivered.
notify-keyspace-events Ex

Yes, the focus is:

notify-keyspace-events Ex

Ex representatives:

# 以  “__keyevent@<db>__“  为前缀发布Keyevent事件,<db>为所使用的redis库编号
1,E: Keyevent events, published with __keyevent@<db>__ prefix.
# 过期事件(每次键过期时生成的事件)
2,x: Expired events (events generated every time a key expires)
1.2, the parameter setting runtime
#设置:
redis-cli: CONFIG SET notify-keyspace-events "Ex"

#查询
redis-cli:CONFIG GET notify-keyspace-event

#redis: 指的是进入redis-cli后,并且执行成功的情况

But this redis restart the service is gone (back to the settings in the configuration file).

2, procedures

2.1, increasing dependencies

pom.xml:

<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.8.22.RELEASE</version>
</dependency>

<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.10.2</version>
</dependency>

# spring用的是4.3.7.RELEASE。需要注意匹配。

Code:

import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;


public class RedisKeyExpiredMessageDelegate implements MessageListener {
    private final String EVENT_CHANNEL = "__keyevent@0__:expired";
    
    @Override
    public void onMessage(Message message, byte[] bytes) {
        if (EVENT_CHANNEL.equalsIgnoreCase(new String(message.getChannel()))) {
            String msg = new String(message.getBody());

            System.out.println(msg + "过期");

        }
    }
}

spring configuration file:

<!-- redis 连接工厂 -->
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
      p:host-name="localhost"
      p:port="6379"/>

<!-- redis消息监听 -->
<bean id="redisMessageListener"
      class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter">
    <constructor-arg>
        <bean class="com.imadiaos.redis.RedisKeyExpiredMessageDelegate" />
    </constructor-arg>
</bean>
<bean id="redisContainer"
      class="org.springframework.data.redis.listener.RedisMessageListenerContainer">
    <property name="connectionFactory" ref="redisConnectionFactory" />
    <property name="messageListeners">
        <map>
            <entry key-ref="redisMessageListener">
                <list>
                    <!--  <bean class="org.springframework.data.redis.listener.ChannelTopic">
                        <constructor-arg value="__keyevent@1__:expired" /> </bean>  -->
                    <!-- <bean class="org.springframework.data.redis.listener.PatternTopic">
                        <constructor-arg value="*" /> </bean> -->
                    <bean class="org.springframework.data.redis.listener.PatternTopic">
                        <constructor-arg value="__key*__:expired" />
                    </bean>
                </list>
            </entry>
        </map>
    </property>
</bean>

Code Example: github.com/imadiaos

Guess you like

Origin www.cnblogs.com/happyeric/p/11359770.html