监听redis key过期事件出现ERR unknown command `CONFIG`, with args beginning with: `GET`, `notify-keyspace-events`这个错误,主要是因为redis配置禁用了CONFIG命令,一些云服务出于安全考虑都会禁用CONFIG命令。
解决办法有两种,一种就是改配置,一种是基于代码层面解决。
方案一:改redis配置文件
注释掉rename-command CONFIG “”,这种方案虽然能解决问题,但是不提倡,禁止redis CONFIG的使用是出于安全考虑的,实际生产中CONFIG 一般是禁止的
方案二:代码层面
只要设置keyspaceNotificationsConfigParameter为null就可以了,为什么这样就能解决这个问题呢?接下来我分析下源码。
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
setKeyspaceNotificationsConfigParameter(null);
}
- KeyspaceEventMessageListener源码:
public abstract class KeyspaceEventMessageListener implements MessageListener, InitializingBean, DisposableBean {
private static final Topic TOPIC_ALL_KEYEVENTS = new PatternTopic("__keyevent@*");
private final RedisMessageListenerContainer listenerContainer;
// 默认的notify-keyspace-events参数为"EA"
private String keyspaceNotificationsConfigParameter = "EA";
/**
* Creates new {@link KeyspaceEventMessageListener}.
*
* @param listenerContainer must not be {@literal null}.
*/
public KeyspaceEventMessageListener(RedisMessageListenerContainer listenerContainer) {
Assert.notNull(listenerContainer, "RedisMessageListenerContainer to run in must not be null!");
this.listenerContainer = listenerContainer;
}
/*
* (non-Javadoc)
* @see org.springframework.data.redis.connection.MessageListener#onMessage(org.springframework.data.redis.connection.Message, byte[])
*/
@Override
public void onMessage(Message message, @Nullable byte[] pattern) {
if (ObjectUtils.isEmpty(message.getChannel()) || ObjectUtils.isEmpty(message.getBody())) {
return;
}
doHandleMessage(message);
}
/**
* Handle the actual message
*
* @param message never {@literal null}.
*/
protected abstract void doHandleMessage(Message message);
/**
* Initialize the message listener by writing requried redis config for {@literal notify-keyspace-events} and
* registering the listener within the container.
* 初始化方法
*/
public void init() {
// 判断keyspaceNotificationsConfigParameter是否为空
if (StringUtils.hasText(keyspaceNotificationsConfigParameter)) {
// 建立redis连接
RedisConnection connection = listenerContainer.getConnectionFactory().getConnection();
try {
// 获取redis配置文件中notify-keyspace-events的值,
// 此处相当于在redis中执行config get notify-keyspace-events
Properties config = connection.getConfig("notify-keyspace-events");
// 判断获取的notify-keyspace-events值是否为空
if (!StringUtils.hasText(config.getProperty("notify-keyspace-events"))) {
// 设置redis配置文件中notify-keyspace-events的值
// 相当于在redis中执行config set notify-keyspace-events xxx
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);
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.DisposableBean#destroy()
*/
@Override
public void destroy() throws Exception {
listenerContainer.removeMessageListener(this);
}
/**
* Set the configuration string to use for {@literal notify-keyspace-events}.
*
* @param keyspaceNotificationsConfigParameter can be {@literal null}.
* @since 1.8
*/
public void setKeyspaceNotificationsConfigParameter(String keyspaceNotificationsConfigParameter) {
this.keyspaceNotificationsConfigParameter = keyspaceNotificationsConfigParameter;
}
/*
* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
init();
}
}
- 源码分析:
通过上面源码我们可以发现源码中调用了redis的CONFIG命令,顺着这个思路,我是否可以设置代码里面不调用redis的CONFIG命令这个问题不久解决了吗?阅读源码,我们发现只要把keyspaceNotificationsConfigParameter 这个参数赋值值null或者空字符串,在init方法中就不会去调用redis的CONFIG命令,我们在往下看源码发现keyspaceNotificationsConfigParameter是提供了set的方法的。所以我们是可以通setKeyspaceNotificationsConfigParameter方法来改变keyspaceNotificationsConfigParameter属性值的。
- 启动结果:
设置keyspaceNotificationsConfigParameter参数为null后,发现程序启动正常
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/121015.html