redis java 监听_从零手写实现redis(四)添加监听器
前言
java從零手寫實現redis(一)如何實現固定大小的緩存?
java從零手寫實現redis(三)redis expire 過期原理
java從零手寫實現redis(三)內存數據如何重啟不丟失?
本節,讓我們來一起學習一下如何實現類似 guava-cache 中的 removeListener 刪除監聽器,和類似 redis 中的慢日志監控的 slowListener。
刪除監聽器
說明
我們在兩種場景下刪除數據是對用戶透明的:
(1)size 滿了之后,進行數據淘汰。
(2)expire 過期時,清除數據。
這兩個特性對用戶本來應該是無感的,不過用戶如果關心的話,也可以通過添加刪除監聽器來獲取到相關的變更信息。
實現思路
為了實現刪除的監聽,我們需要找到刪除的位置,然后調用監聽器即可。
evict 驅除的場景
每次 put 數據時,都會校驗 size 是否達到最大的限制,如果達到,則進行 evict 淘汰。
expire 過期的場景
用戶指定 expire 時間之后,回后臺異步執行刷新。
也存在惰性刪除的場景。
接口定義
為了統一,我們將所有的刪除都定義統一的接口:
/*** 刪除監聽器接口** @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);}內置實現
系統內置的實現如下:
public class CacheRemoveListener<K,V> implements ICacheRemoveListener<K,V> {private static final Log log = LogFactory.getLog(CacheRemoveListener.class);@Overridepublic void listen(ICacheRemoveListenerContext<K, V> context) {log.debug("Remove key: {}, value: {}, type: {}",context.key(), context.value(), context.type());}}這個監聽器是默認開啟的,暫時無法關閉。
自定義
用戶可以自己的需要,進行自定義實現:
public class MyRemoveListener<K,V> implements ICacheRemoveListener<K,V> {@Overridepublic void listen(ICacheRemoveListenerContext<K, V> context) {System.out.println("【刪除提示】可惡,我竟然被刪除了!" + context.key());}}測試
ICache<String, String> cache = CacheBs.<String,String>newInstance().size(1).addRemoveListener(new MyRemoveListener<String, String>()).build();cache.put("1", "1"); cache.put("2", "2");我們指定 cache 的大小為1,設置我們自定義的刪除監聽器。
這里的刪除監聽器可以添加多個。
日志
測試日志如下:
[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慢操作監聽器
說明
redis 中會存儲慢操作的相關日志信息,主要是由兩個參數構成:
(1)slowlog-log-slower-than 預設閾值,它的單位是毫秒(1秒=1000000微秒)默認值是10000
(2)slowlog-max-len 最多存儲多少條的慢日志記錄
不過 redis 是直接存儲到內存中,而且有長度限制。
根據實際工作體驗,如果我們可以添加慢日志的監聽,然后有對應的存儲或者報警,這樣更加方便問題的分析和快速反饋。
所以我們引入類似于刪除的監聽器。
實現思路
我們處理所有的 cache 操作,并且記錄對應的操作耗時。
如果耗時操作用戶設置的時間閾值,則調用慢操作監聽器。
接口定義
為了保證接口的靈活性,每一個實現都可以定義自己的慢操作閾值,這樣便于分級處理。
比如超過 100ms,用戶可以選擇輸出 warn 日志;超過 1s,可能影響到業務了,可以直接接入報警系統。
public interface ICacheSlowListener {/*** 監聽* @param context 上下文* @since 0.0.6*/void listen(final ICacheSlowListenerContext context);/*** 慢日志的閾值* @return 慢日志的閾值* @since 0.0.9*/long slowerThanMills();}自定義監聽器
實現接口 ICacheSlowListener
這里每一個監聽器都可以指定自己的慢日志閾值,便于分級處理。
public class MySlowListener implements ICacheSlowListener {@Overridepublic void listen(ICacheSlowListenerContext context) {System.out.println("【慢日志】name: " + context.methodName());}@Overridepublic long slowerThanMills() {return 0;}}使用
ICache<String, String> cache = CacheBs.<String,String>newInstance().addSlowListener(new MySlowListener()).build();cache.put("1", "2"); cache.get("1");- 測試效果
實際工作中,我們可以針對慢日志數據存儲,便于后期分析。
也可以直接接入報警系統,及時反饋問題。
小結
監聽器實現起來比較簡單,但是對于使用者的作用是比較大的。
文中主要講述了思路,實現部分因為篇幅限制,沒有全部貼出來。
開源地址:https://github.com/houbb/cache覺得本文對你有幫助的話,歡迎點贊評論收藏關注一波~
你的鼓勵,是我最大的動力~
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的redis java 监听_从零手写实现redis(四)添加监听器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cass直线连接快捷键(cass正交快捷
- 下一篇: 金蝶系统凭证如何批量反审核(金蝶凭证反审