当前位置:网站首页>JetCache埋点的骚操作,不服不行啊
JetCache埋点的骚操作,不服不行啊
2020-11-06 01:28:00 【尹吉欢】
阐述背景
缓存是应对高并发绝对的利器,在很多业务场景允许的情况下,都可以使用缓存来提供性能。
既然用了缓存,那对缓存进行监控必不可少。比如缓存加载耗时,新增耗时等。
在 JetCache 中进行埋点操作,对于 Redis 的缓存没有问题,埋点之后的 Key 是完整的,完整的也就是 Cache 的 name+key,如下图:

除了对 Redis 的缓存做埋点,还对本地 缓存 Caffeine 也做了埋点操作,然后发现 Caffeine 的埋点有问题,问题在于 Cache 的 name 丢失了,如下图:

然后去官方的钉钉群了问了下维护人员,让我升级版本。然后我升级到最新的 2.6.0 还是不行,这不是坑我么!
找出原因
正所谓自己动手,丰衣足食。直接看代码吧,首先看 Redis 为何 Cache name 没有丢失,原因是 Redis 的 Config 中有 keyPrefix,如下图:

然后在对 Redis 进行操作的时候,会构建缓存的 Key,构建 Key 的时候会带上 keyPrefix,所以 Redis 的 Key 是正常的。
com.alicp.jetcache.external.AbstractExternalCache
public byte[] buildKey(K key) {try {Object newKey = key;if (key instanceof byte[]) {newKey = key;} else if (key instanceof String) {newKey = key;} else if (this.config.getKeyConvertor() != null) {newKey = this.config.getKeyConvertor().apply(key);}return ExternalKeyUtil.buildKeyAfterConvert(newKey, this.config.getKeyPrefix());} catch (IOException var3) {throw new CacheException(var3);}}
然后来看 Caffeine 的 config 中是没有 Keyprefix 的,如下图:

然后在构建缓存 Key 的时候,也就是没有 Keyprefix,所以问题就出在这里。
com.alicp.jetcache.embedded.AbstractEmbeddedCache
public Object buildKey(K key) {if (key == null) {return null;} else {Object newKey = key;Function<K, Object> keyConvertor = this.config.getKeyConvertor();if (keyConvertor != null) {newKey = keyConvertor.apply(key);}return newKey;}}
RedisCacheConfig 继承了 ExternalCacheConfig,ExternalCacheConfig 继承了 CacheConfig。
keyPrefix 定义在 ExternalCacheConfig 中。

而 EmbeddedCacheConfig 只继承了 CacheConfig,所以它自然就没有 keyPrefix 字段。

解决方案
原因找出来了,想要解决肯定是可以的。问题是这是个开源的框架,不是自己公司内部的代码。不过也可以直接将源码克隆下来,进行改造,然后打包发布到自己的私服中去就可以了。
将 EmbeddedCacheConfig 也继承 ExternalCacheConfig 就可以将 keyPrefix 透传下去,然后在 buildKey 的地方进行拼接。
还有一种比较投机取巧的方案,可以不用改变配置类的关系,在 config 中有 monitors 这个信息,里面存放的是缓存的监控信息,主要是记录缓存对应的操作类型,GET, PUT 这种,然后就是每个操作的执行时间,操作次数等一些统计的信息,最终会有一个线程定时将这些信息输出到日志中。
所以我们可以通过获取 monitors 中的 cacheName 来临时解决这个问题。

private String getCacheName() {List<CacheMonitor> monitors = config.getMonitors();if (CollectionUtils.isEmpty(monitors)) {return "";}DefaultCacheMonitor cacheMonitor = (DefaultCacheMonitor) monitors.get(0);String cacheName = cacheMonitor.getCacheName();return cacheName;}
功能代码: https://github.com/yinjihuan/kitty
关于作者 :尹吉欢,简单的技术爱好者,《Spring Cloud 微服务-全栈技术与案例解析》, 《Spring Cloud 微服务 入门 实战与进阶》作者, 公众号 猿天地 发起人。个人微信 jihuan900 ,欢迎勾搭。
我整理了一份很全的学习资料,感兴趣的可以微信搜索 「猿天地」,回复关键字 「学习资料」获取我整理好了的Spring Cloud,Spring Cloud Alibaba,Sharding-JDBC分库分表,任务调度框架XXL-JOB,MongoDB,爬虫等相关资料。

版权声明
本文为[尹吉欢]所创,转载请带上原文链接,感谢
http://cxytiandi.com/blog/detail/36498
边栏推荐
猜你喜欢

网络安全工程师演示:原来***是这样获取你的计算机管理员权限的!【***】

面经手册 · 第15篇《码农会锁,synchronized 解毒,剖析源码深度分析!》

Working principle of gradient descent algorithm in machine learning

Using lime to explain black box ML model

文本去重的技术方案讨论(一)

mongodb(从0到1),11天mongodb初级到中级进阶秘籍

读取、创建和运行多个文件的3个Python技巧

JVM内存区域与垃圾回收

写一个通用的幂等组件,我觉得很有必要

JVM Metaspace内存溢出排查与总结
随机推荐
如何使用ES6中的参数
Using tensorflow to forecast the rental price of airbnb in New York City
被产品经理怼了,线上出Bug为啥你不知道
7.2.1 cache configuration of static resources
如何将分布式锁封装的更优雅
别走!这里有个笔记:图文讲解 AQS ,一起看看 AQS 的源码……(图文较长)
How to select the evaluation index of classification model
ES6精华:Proxy & Reflect
【快速因數分解】Pollard's Rho 演算法
50+开源项目正式集结完毕,百万开发者正在投票
基础知识点整理
6.8 multipartresolver file upload parser (in-depth analysis of SSM and project practice)
Outlier detection based on RNN self encoder
vite + ts 快速搭建 vue3 專案 以及介紹相關特性
leetcode之赎金信
Skywalking系列博客2-Skywalking使用
VuePress的使用
文本去重的技术方案讨论(一)
接口压力测试:Siege压测安装、使用和说明
企业数据库的选择通常由系统架构师主导决策 - thenewstack