Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How does SpringBoot monitor the change of a Key in Redis

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces how SpringBoot monitors the changes of a Key in Redis. It has a certain reference value, and interested friends can refer to it. I hope you will gain a lot after reading this article. Let's take a look at it.

SpringBoot monitors the change of a Key in Redis 1. Statement

The current content is mainly for self-study and basic testing, mainly to monitor the changes of a certain key in redis (feel that nothing on the Internet is good, so look at the Spring source code and write a listener directly)

Personal reference:

Redis official documentation

Spring-data-Redis source code

two。 Basic idea

Disadvantages of demo on the Internet

Using inherited KeyExpirationEventMessageListener can only listen for events where the current key disappears

Using KeyspaceEventMessageListener can only listen to all key events

In general, you cannot listen for changes in a particular key (a particular redis database), which is flawed

Analyze directly to get the steps that can be operated

Check the source code of KeyspaceEventMessageListener to solve the problem.

Basic thought

Create your own theme (to listen on a specific key)

Create listeners to implement MessageListener

Inject your own configuration information

View the method in it (init method)

Public void init () {if (StringUtils.hasText (keyspaceNotificationsConfigParameter)) {RedisConnection connection = listenerContainer.getConnectionFactory () .getConnection (); try {Properties config = connection.getConfig ("notify-keyspace-events") If (! StringUtils.hasText (config.getProperty ("notify-keyspace-events") {connection.setConfig ("notify-keyspace-events", keyspaceNotificationsConfigParameter);}} finally {connection.close () }} doRegister (listenerContainer);} / * * Register instance within the container. * * @ param container never {@ literal null}. * / protected void doRegister (RedisMessageListenerContainer container) {listenerContainer.addMessageListener (this, TOPIC_ALL_KEYEVENTS);}

The main operations are as follows

Write configuration notify-keyspace-events to redis and set it to EA

Add the listener itself to the RedisMessageListenerContainer and specify the listener topic

So what I lack is the topic expression and the notify-keyspace-events configuration for listening.

Go directly to the official documentation of redis to find the following

So the direct choice is: _ _ keyspace@0__:myKey, and the mode used is KEA

Start to monitor after all the work is done.

3. Implement and create snooping

Create a listening class: RedisKeyChangeListener

This class mainly listens to the key of myKey of database 0 in redis.

Import java.nio.charset.Charset;import java.util.Properties;import org.springframework.data.redis.connection.Message;import org.springframework.data.redis.connection.MessageListener;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.listener.KeyspaceEventMessageListener;import org.springframework.data.redis.listener.PatternTopic;import org.springframework.data.redis.listener.RedisMessageListenerContainer;import org.springframework.data.redis.listener.Topic;import org.springframework.util.StringUtils / * @ author hy * @ createTime 2021-05-01 08:53:19 * @ description expects to be able to monitor changes in a key rather than invalidate * * / public class RedisKeyChangeListener implements MessageListener/* extends KeyspaceEventMessageListener * / {private final String listenerKeyName; / / the name of the monitored key private static final Topic TOPIC_ALL_KEYEVENTS = new PatternTopic ("_ _ keyevent@*") / / means to listen only to all key private static final Topic TOPIC_KEYEVENTS_SET = new PatternTopic ("_ _ keyevent@0__:set"); / / means to listen only to all key private static final Topic TOPIC_KEYNAMESPACE_NAME = new PatternTopic ("_ _ keyspace@0__:myKey") / / not effective / / Monitoring / / private static final Topic TOPIC_KEYEVENTS_NAME_SET_USELESS = new PatternTopic ("_ _ keyevent@0__:set myKey"); private String keyspaceNotificationsConfigParameter = "KEA"; public RedisKeyChangeListener (RedisMessageListenerContainer listenerContainer, String listenerKeyName) {this.listenerKeyName = listenerKeyName; initAndSetRedisConfig (listenerContainer) } public void initAndSetRedisConfig (RedisMessageListenerContainer listenerContainer) {if (StringUtils.hasText (keyspaceNotificationsConfigParameter)) {RedisConnection connection = listenerContainer.getConnectionFactory () .getConnection (); try {Properties config = connection.getConfig ("notify-keyspace-events") If (! StringUtils.hasText (config.getProperty ("notify-keyspace-events") {connection.setConfig ("notify-keyspace-events", keyspaceNotificationsConfigParameter);}} finally {connection.close () }} / / Registration message listener listenerContainer.addMessageListener (this, TOPIC_KEYNAMESPACE_NAME);} @ Override public void onMessage (Message message, byte [] pattern) {System.out.println ("key changes = =" + message) " Byte [] body = message.getBody (); String string = new String (body, Charset.forName ("utf-8")); System.out.println (string);}}

In fact, only a few places have been changed.

4. Other configurations of basic demo

1.RedisConfig configuration class

@ Configuration@PropertySource (value = "redis.properties") @ ConditionalOnClass ({RedisConnectionFactory.class, RedisTemplate.class}) public class RedisConfig {@ Autowired RedisProperties redisProperties / * * @ author hy * @ createTime 2021-05-01 08:40:59 * @ description basic redisPoolConfig * @ return * * / private JedisPoolConfig jedisPoolConfig () {JedisPoolConfig config = new JedisPoolConfig (); config.setMaxIdle (redisProperties.getMaxIdle ()) Config.setMaxTotal (redisProperties.getMaxTotal ()); config.setMaxWaitMillis (redisProperties.getMaxWaitMillis ()); config.setTestOnBorrow (redisProperties.getTestOnBorrow ()); return config } / * @ description create redis connection factory * / @ SuppressWarnings ("deprecation") private JedisConnectionFactory jedisConnectionFactory () {JedisConnectionFactory factory = new JedisConnectionFactory (new JedisShardInfo (redisProperties.getHost (), redisProperties.getPort (); factory.setPassword (redisProperties.getPassword ()) Factory.setTimeout (redisProperties.getTimeout ()); factory.setPoolConfig (jedisPoolConfig ()); factory.setUsePool (redisProperties.getUsePool ()); factory.setDatabase (redisProperties.getDatabase ()); return factory } / * * @ description create the operation class of RedisTemplate * / @ Bean public StringRedisTemplate getRedisTemplate () {StringRedisTemplate redisTemplate = new StringRedisTemplate (); redisTemplate.setConnectionFactory (jedisConnectionFactory ()); redisTemplate.setEnableTransactionSupport (true); return redisTemplate } @ Bean public RedisMessageListenerContainer redisMessageListenerContainer () throws Exception {RedisMessageListenerContainer container = new RedisMessageListenerContainer (); container.setConnectionFactory (jedisConnectionFactory ()); return container } / / create a basic key listener / * * / @ Bean public RedisKeyChangeListener redisKeyChangeListener () throws Exception {RedisKeyChangeListener listener = new RedisKeyChangeListener (redisMessageListenerContainer (), "); return listener;}}

The most important of these are RedisMessageListenerContainer and RedisKeyChangeListener.

two。 Another RedisProperties class that loads the redis.properties file and becomes the object's

/ * @ author hy * @ createTime 2021-05-01 08:38:26 * @ description basic redis configuration class * * / @ ConfigurationProperties (prefix = "redis") public class RedisProperties {private String host; private Integer port; private Integer database; private Integer timeout; private String password; private Boolean usePool; private Integer maxTotal; private Integer maxIdle; private Long maxWaitMillis Private Boolean testOnBorrow; private Boolean testWhileIdle; private Integer timeBetweenEvictionRunsMillis; private Integer numTestsPerEvictionRun; / / omit get\ set method}

Omit other code

5. Basic test

Create a key and modify to find changes

You can find that the method (set) executed by this key is returned. If you are using keyevent mode, then the name of the key is returned.

6. Make a brief summary

1. The change of key in monitoring redis is mainly realized by the mechanism of redis (itself is publish / subscribe)

two。 It is not enabled by default, and the reason is that it consumes cpu

3. When implementing, you need to look at the official redis documentation and the source code of SpringBoot to solve the practical problems.

Principle of SpringBoot custom listener

According to the listening objects, Listener can be divided into:

The event listeners that listen to ServletContext are: ServletContextListener and ServletContextAttributeListener. At the Application level, there is only one application, which can be configured globally.

The event listeners that listen to HttpSeesion are: HttpSessionListener and HttpSessionAttributeListener. Session level, for each object, such as the total number of sessions.

The event listeners that listen to ServletRequest are: ServletRequestListener and ServletRequestAttributeListener. Request level, for each customer request.

Example

Step 1: create a project and add dependencies

Org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat provided javax.servlet jstl 1.2 compile org.apache.tomcat.embed tomcat-embed-jasper compile org.eclipse.jdt.core.compiler ecj 4.6.1

Step 2: customize the listener

@ WebListenerpublic class MyServletRequestListener implements ServletRequestListener {@ Override public void requestDestroyed (ServletRequestEvent sre) {System.out.println ("Request listener, destroy");} @ Override public void requestInitialized (ServletRequestEvent sre) {System.out.println ("Request listener, initialize");}}

Step 3: define Controller

RestControllerpublic class DemoController {@ RequestMapping ("/ fun") public void fun () {System.out.println ("fun");}}

Step 4: add comments to the program execution entry class

@ ServletComponentScan

To deploy the project, run to view the results:

Thank you for reading this article carefully. I hope the article "how to monitor the change of a certain Key in Redis" shared by the editor will be helpful to everyone. At the same time, I also hope that you will support and follow the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report