HotKey 热点探测

项目背景:

通常项目中,我们采用 grafana和prometheus 作为项目监控通常都是按照秒级别的采样监控,但是无法检测一个接口,一个热点用户毫秒级的监控。 hotkey 项目是一个针对热点探测,监控。将请求数据缓推送到服务端的 jvm 内存中,减少后端存储对持久化数据库的冲击,可以由使用者决定如何分配、使用这些热点 key , 可以用来做本地缓存,拒绝访问,热点熔断返回默认值等。这些数据在集群内能够保证一致性,实现业务隔离。 hotkey 是京东APP后台热数据探测框架,历经多次高压压测和2020年京东618、双11大促考验。每秒单机吞吐量(写入+对外推送)目前在70万左右稳定。

gitee 项目地址:

gitee.com/jd-platform…

系统架构:

hotkey 采用的分布式集群架构,默认以 etcd 为服务注册中心,然后 hotkey-client 通过 etcd 获取 worker 的信息, 将监听到的热key 信息上报到 worker 上。在 hotkey-client 和 worker 之间采用长链接的方式(基于 netty)然后按照 key 的 hash 算法,分发到不同的 worker 进行计算。最后 worker 将计算出来的热 key 在进行推送到 hotkey-client 进行内存缓存。

image.png

安装步骤:

安装 etcd 作为注册中心

docker 安装命令

docker run -d \                                                                         
  -p 12379:2379 \
  -p 12380:2380 \
  -v /Users/zhengshaohong/etcd/data:/etcd-data/member \
  --name exam-etcd \
   quay.io/coreos/etcd:latest \
  /usr/local/bin/etcd \
  --name s1 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://0.0.0.0:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://0.0.0.0:2380 \
  --initial-cluster s1=http://0.0.0.0:2380 \
  --initial-cluster-token tkn \
  --initial-cluster-state new

测试:

# 创建数据
docker exec exam-etcd etcdctl --endpoints=http://127.0.0.1:2379 set test_key hello_world

# 查询数据
docker exec exam-etcd etcdctl --endpoints=http://127.0.0.1:2379 get test_key

安装 hotkey dashboard

  1. 下载代码: gitee.com/jd-platform…
  2. 初始化数据库,脚本位置 dashboard/src/main/resources/db.sql 初始化脚本过后,我们需要检查密码是否正确 image.png 如果不匹配修改 3)然后启动: dashboard 4)访问 dashboard, ip:8081 默认登陆账户 admin , 密码:123456 登陆页面如下: image.png

启动 worker

启动命令

java -jar $JAVA_OPTS worker-0.0.4-SNAPSHOT.jar --etcd.server=http://127.0.0.1:2379

app 配置规则 登陆 dashboard 后可以看到这个页面 image.png 创建用户,需要注意这个地方的用户名就是服务名, 可以选择新增按钮新增。 image.png

配置规则

image.png 规则配置代码示例:

[{"desc":"* hotkey ","duration":60,"interval":5,"key":"*","prefix":false,"threshold":3}]

配置 JSON 说明:

  • key-(*代表任意以key为前缀),
  • prefix-是否前缀,
  • interval-间隔时间(秒),
  • threshold-阈值,
  • duration-缓存时间(秒),默认60

客户端集成 hotkey-client 引入 hotkey-client 依赖

<dependency>
    <groupId>com.jd.platform.hotkey</groupId>
    <artifactId>hotkey-client</artifactId>
    <version>${version}</version>
</dependency>

初始化 hotkey client


@Component
public class HotKeyConfig {
    @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();
    }
}

使用 hotkey api

@RestController
@RequestMapping
public class TestController {

    @Resource
    private Cache cache;
    private Logger logger = LoggerFactory.getLogger(getClass());

    @RequestMapping("/hotKey")
    public Object hotKey(String key) {
        if (!StringUtils.isEmpty(key) && JdHotKeyStore.isHotKey(key)) {
            return "isHot";
        } else {
            return "noHot";
        }
    }
}

测试

访问 /hotkey 接口,触发阈值过后就会显示 image.png dashboad 查看实时热点如下 image.png 通过查询这个控制台,我们就很容易知道系统的热点位置,方便我们下一步的性能优化。

参考文档:

gitee.com/jd-platform… mp.weixin.qq.com/s/xOzEj5HtC…

猜你喜欢

转载自juejin.im/post/7240475280217505853