对任意突发性的无法预先感知的热点数据,包括并不限于热点数据(如突发大量请求同一个商品)、热用户(如恶意爬虫刷子)、热接口(突发海量请求同一个接口)等,进行毫秒级精准探测到。然后对这些热数据、热用户等,推送到所有服务端JVM内存中,以大幅减轻对后端数据存储层的冲击,并可以由使用者决定如何分配、使用这些热key(譬如对热商品做本地缓存、对热用户进行拒绝访问、对热接口进行熔断或返回默认值)。这些热数据在整个服务端集群内保持一致性,并且业务隔离,worker端性能强悍。
适用场景:
1 mysql热数据本地缓存
2 redis热数据本地缓存
3 黑名单用户本地缓存
4 爬虫用户限流
5 接口、用户维度限流
6 单机接口、用户维度限流
7 集群用户维度限流
8 集群接口维度限流
环境部署
1 下载hotkey源码
hotkey: 京东App后台中间件,毫秒级探测热点数据,毫秒级推送至服务器集群内存,大幅降低热key对数据层查询压力
选择master分支下载

2 下载etcd
相当于注册中心作用
根据其文档,需要先启动etcd服务,下载地址:Releases · etcd-io/etcd

双击启动


3 启动worker
项目打包



启动服务
java -jar worker-0.0.4-SNAPSHOT.jar --etcd.server=http://127.0.0.1:2379 --etcd.workerPath=myapp
本例指定了etcd地址和workPath(控制台添加规则时,app名称要和该值保持一致)

4 启动dashboard
新建数据库 hotkey_db,并导入表,表来自db.sql


启动dashboard
java -jar dashboard-0.0.2-SNAPSHOT.jar --etcd.server=http://127.0.0.1:2379

访问http://127.0.0.1:8081(端口号可以通过dashboard的yml配置文件指定)

项目中接入hotkey
新建springboot项目
导入jar
文档中只是提到了导入client的jar,但是没有提到具体的jar的配置
开始导入了如下的jar,但是实际测试时,无法检测hotkey
<!-- 该jar无法使hotkey生效 -->
<dependency>
<groupId>io.github.ck-jesse</groupId>
<artifactId>jd-hotkey-client</artifactId>
<version>2.0.0</version>
</dependency>
只能对源码的client进行打包并导入

在springboot项目中新建lib目录,拷贝hotkey-client-0.0.4-SNAPSHOT-jar-with-dependencies.jar到lib目录

通过maven导入该jar
<dependency>
<groupId>com.jd.platform.hotkey</groupId>
<artifactId>hotkey-client</artifactId>
<version>0.0.4-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/hotkey-client-0.0.4-SNAPSHOT-jar-with-dependencies.jar</systemPath>
</dependency>
yml配置
#etcd的地址,如有多个用逗号分隔
etcd:
server: ${etcdServer:https://127.0.0.1:2379}
# server: ${etcdServer:http://10.170.161.91:2379}
# server: http://open-etcd.jd.com:2000
spring:
application:
name: ${name:myapp}
###############################---redis---##############################
# redis:
# host: ${REDIS_HOST:127.0.0.1}
# port: ${REDIS_PORT:6379}
# password: ${REDIS_PASSWORD:}
server:
port: 9999
读取yml并初始化对象
package com.qfedu.hotkeytest;
import com.jd.platform.hotkey.client.ClientStarter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@Component
public class Starter {
@Value("${etcd.server}")
private String etcd;
@Value("${spring.application.name}")
private String appName;
@PostConstruct
public void init() {
ClientStarter.Builder builder = new ClientStarter.Builder();
ClientStarter starter = builder.setAppName(appName).setEtcdServer(etcd).build();
starter.startPipeline();
}
}
在dashboard中添加用户
添加用户时指定app名称,和启动worker时指定的workPath值保持一致

添加规则

本例表示,5秒内,访问aaa前缀的key超过10次,则认为是热点key,并缓存60秒
通过控制层测试
@RequestMapping("/hotKey")
public Object hotKey(String key) {
if (!StringUtils.isEmpty(key) && JdHotKeyStore.isHotKey(key)) {
return "isHot";
} else {
return "noHot";
}
}

5秒内,访问该接口超过10次,自动生成缓存

jd-hotkey通过Caffeine将数据缓存到服务器的jvm内存中
2470

被折叠的 条评论
为什么被折叠?



