jd-etcd热key探测,对redis热key,热请求进行
简介
对任意突发性的无法预先感知的热点数据,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后对这些热数据、热用户等,推送到所有服务端JVM内存中。
hotkey框架的主要组成部分
-
etcd
etcd作为⼀个⾼性能的配置中⼼,可以以极⼩的资源占⽤,提供⾼效的监听订阅服务。主要⽤于存放规则配置,各worker的ip地址,以及探测出的热key、⼿⼯添加的热key等
-
worker
worker端是⼀个独⽴部署的Java程序,启动后会连接etcd,并定期上报⾃⼰的ip信息,供client端获取地址并进⾏⻓连接。之后,主要就是对各个client发来的待测key进⾏累加计算,当达到etcd⾥设定的rule阈值后,将热key推送各个client。
dashboard
控制台是⼀个带可视化界⾯的Java程序,也是连接到etcd,之后在控制台设置各个APP的key规则,譬如2秒出现20次算热key。然后当worker探测出来热key后,会将key发往etcd,dashboard也会监听热key信息,进⾏⼊库保存记录。同时,dashboard也可以⼿⼯添加、删除热key,供各个client端监听。
-
client
在服务中添加的引⽤jar,引⼊后,就可以以便捷的⽅式去判断某key是否热key。同时,该jar完成了key上报、监听etcd⾥的rule变化、worker信息变化、热key变化,对热key进⾏本地caffeine缓存等.
安装
源码地址:
https://gitee.com/jd-platform-opensource/hotkey
测试可以直接下载源码下载直接跑,新建dashboard的数据库,更改数据库连接就可以直接启动了
etcd安装
- 下载 (使用3.4.x以上对应自己系统的版本)
https://github.com/coreos/etcd/releases
// 参考
https://www.cnblogs.com/pyrene/p/8652879.html
- 解压 进入解压目录执行 etcd.exe 出现端口号不报错说明启动成功了。
启动worker
-
worker 已经打好的jar包,下载地址
https://gitee.com/dssss/resource-library/tree/master/jd-hotkey/worker
-
启动服务 java -jar worker-0.0.4-SNAPSHOT.jar --etcd.server=127.0.01:2379
启动 dashboard
-
dashboard jar包下载地址
https://gitee.com/dssss/resource-library/tree/master/jd-hotkey/dashboard
-
启动服务( 这个需要创建数据库并导入resource下db.sql文件。 配置一下application.yml里的数据库相关和etcdServer地址) java -jar dashboard-0.0.2-SNAPSHOT.jar
-
访问 http://127.0.0.1:8081 账号:admin 密码:123456
在springboot中使用
- 配置app规则 在用户管理菜单中,添加一个新用户,设置他的APP名字,如hostkey。之后新添加的这个用户就可以登录dashboard给自己的APP设置规则了
[ { "desc":"* hotkey ", "duration":60, "interval":5, "key":"*", "prefix":false, "threshold":3 } ]
引入client jar包
<dependency>
<groupId>com.jd.platform.hotkey</groupId>
<artifactId>hotkey-client</artifactId>
<version>0.0.4-SNAPSHOT</version>
</dependency>
初始化
@Component
public class HotKeyInit {
@Value("${etcd.server}")
private String etcdServer;
@Value("${spring.application.name}")
private String appName;
@PostConstruct
public void init() {
ClientStarter.Builder builder = new ClientStarter.Builder();
ClientStarter starter = builder.setAppName(appName).setEtcdServer(etcdServer).build();
starter.startPipeline();
}
}
测试
@RestController
public class TestController {
@RequestMapping("/hotKey")
public Object hotKey(String key) {
if (!StringUtils.isEmpty(key) && JdHotKeyStore.isHotKey(key)) {
return "isHot";
} else {
return "noHot";
}
}
}
api方法
-
boolean isHotKey(String key) ,该方法会返回该key是否是热key,如果是返回true,如果不是返回false,并且会将key上报到探测集群进行数量计算。该方法通常用于判断只需要判断key是否热、不需要缓存value的场景,如刷子用户、接口访问频率等。
-
Object get(String key),该方法返回该key本地缓存的value值,可用于判断是热key后,再去获取本地缓存的value值,通常用于redis热key缓存
-
void smartSet(String key, Object value),方法给热key赋值value,如果是热key,该方法才会赋值,非热key,什么也不做
-
Object getValue(String key),该方法是一个整合方法,相当于isHotKey和get两个方法的整合,该方法直接返回本地缓存的value。 如果是热key,则存在两种情况,1是返回value,2是返回null。返回null是因为尚未给它set真正的value,返回非null说明已经调用过set方法了,本地缓存value有值了。 如果不是热key,则返回null,并且将key上报到探测集群进行数量探测。
-
其他查看 JdHotKeyStore 类