从零手写实现redis(四)添加监听器

1、删除监听器

复制代码
/**
 * 删除监听器接口
 *
 * @author binbin.hou
 * @since 0.0.6
 * @param <K> key
 * @param <V> value
 */
public interface ICacheRemoveListener<K,V> {

    /**
     * 监听
     * @param context 上下文
     * @since 0.0.6
     */
    void listen(final ICacheRemoveListenerContext<K,V> context);

}

为了统一,我们将所有的删除都定义统一的接口

2、内置实现

复制代码
public class CacheRemoveListener<K,V> implements ICacheRemoveListener<K,V> {

    private static final Log log = LogFactory.getLog(CacheRemoveListener.class);

    @Override
    public void listen(ICacheRemoveListenerContext<K, V> context) {
        log.debug("Remove key: {}, value: {}, type: {}",
                context.key(), context.value(), context.type());
    }

}

这个监听器是默认开启的,暂时无法关闭。

3、自定义

复制代码
public class MyRemoveListener<K,V> implements ICacheRemoveListener<K,V> {

    @Override
    public void listen(ICacheRemoveListenerContext<K, V> context) {
        System.out.println("【删除提示】可恶,我竟然被删除了!" + context.key());
    }

}

用户可以自己的需要,进行自定义实现

4、测试

复制代码
ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .size(1)
        .addRemoveListener(new MyRemoveListener<String, String>())
        .build();

cache.put("1", "1");
cache.put("2", "2");


[DEBUG] [2020-09-30 19:32:54.617] [main] [c.g.h.c.c.s.l.r.CacheRemoveListener.listen] - Remove key: 2, value: 2, type: evict
【删除提示】可恶,我竟然被删除了!2

5、慢操作监听器

redis 中会存储慢操作的相关日志信息,主要是由两个参数构成:

(1)slowlog-log-slower-than 预设阈值,它的单位是毫秒(1秒=1000000微秒)默认值是10000

(2)slowlog-max-len 最多存储多少条的慢日志记录

不过 redis 是直接存储到内存中,而且有长度限制。

根据实际工作体验,如果我们可以添加慢日志的监听,然后有对应的存储或者报警,这样更加方便问题的分析和快速反馈。

所以我们引入类似于删除的监听器。

6、接口定义

复制代码
public interface ICacheSlowListener {

    /**
     * 监听
     * @param context 上下文
     * @since 0.0.6
     */
    void listen(final ICacheSlowListenerContext context);

    /**
     * 慢日志的阈值
     * @return 慢日志的阈值
     * @since 0.0.9
     */
    long slowerThanMills();

}

为了保证接口的灵活性,每一个实现都可以定义自己的慢操作阈值,这样便于分级处理。

比如超过 100ms,用户可以选择输出 warn 日志;超过 1s,可能影响到业务了,可以直接接入报警系统。

7、自定义监听器

复制代码
public class MySlowListener implements ICacheSlowListener {

    @Override
    public void listen(ICacheSlowListenerContext context) {
        System.out.println("【慢日志】name: " + context.methodName());
    }

    @Override
    public long slowerThanMills() {
        return 0;
    }

}

实现接口 ICacheSlowListener

这里每一个监听器都可以指定自己的慢日志阈值,便于分级处理。

8、使用

复制代码
ICache<String, String> cache = CacheBs.<String,String>newInstance()
        .addSlowListener(new MySlowListener())
        .build();

cache.put("1", "2");
cache.get("1");

[DEBUG] [2020-09-30 17:40:11.547] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.before] - Cost start, method: put
[DEBUG] [2020-09-30 17:40:11.551] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.after] - Cost end, method: put, cost: 10ms
【慢日志】name: put
[DEBUG] [2020-09-30 17:40:11.554] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.before] - Cost start, method: get
[DEBUG] [2020-09-30 17:40:11.554] [main] [c.g.h.c.c.s.i.c.CacheInterceptorCost.after] - Cost end, method: get, cost: 1ms
【慢日志】name: get
相关推荐
Flittly1 小时前
【AgentScope Java新手村系列】(16)从RAG到多路检索
java·spring boot·spring
小兔崽子去哪了1 小时前
Java 生成二维码解决方案
java·后端
人活一口气6 小时前
从JVM调优到MCP协议:Java全栈技术体系深度总结与企业级架构实践
java·spring boot
NE_STOP8 小时前
Vibe Coding -- 完整项目案例实操
java
荣码8 小时前
GraphRAG:普通RAG只能回答"点"的问题,我踩了4个坑才搞懂
java·python
SimonKing8 小时前
Google第三方授权登录
java·后端·程序员
明月光8188 小时前
从一行 @Builder 说起:重新拾起 Java 的 Lombok、注解与 Builder 模式
java
考虑考虑17 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯18 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
青石路1 天前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java