kafka interceptor
能够拦截,所有kafka client
接收或发送的消息, 基于这一点,我们可以在消息被拦截到时,进行消息统计以及相应的延时计算;
需要明白一个点
kafka
在0.10.0
版本, 开始支持每个record
带一个timestamp
. KafkaProducer
发送的record
所带有的ts
比较特别, 你可以在创建ProducerRecord
时,设置该record
的时间戳, 如果你没有给ProducerRecord
设置时间戳; 那么这个消息的时间戳会被设置为kafka broker
接收此消息的时间戳. 所以KafkaConsumer
订阅得到的record
,所带有的时间戳可能是该record
创建的时间,或者是record
被接受的时间戳.
所以KafkaProducer
产生的消息是不进行延时计算的(我觉得这个是没有必要的). 对于KafkaConsumer
订阅得到的消息, 我把消息带有的时间戳和当前时间的差作为延时. 所以这里也需要明白, 如果KafkaConsumer
从头开始消费Topic
数据,那么这时候的延时可能会无比巨大(这些延时可能没有参考价值了).
如何基于interceptor审计消息
时间桶的概念
我们将时间以固定的间隔分段, 每个时间段称为一个时间桶. 时间桶包含了这个时间段内, kafka client
接收, 发送的record
个数, 以及KafkaConsumer
订阅得到的record
相关延时数据(c95
延时, c99
延时, 平均延时和最大延时);
每个record
会被落到哪个时间桶内?
当拦截器收到一个record
时, 我们记录kafka client
收到record
的时间, 用这个时间计算获得record
所在的时间桶.
为什么不用record
所带的时间戳计算时间桶?
KafkaProducer
发送的record
不一定都带有TS
, 也就无法计算该record
所在的时间桶.KafkaConsumer
订阅得到record
, 它带有的时间戳对应的时间桶, 可能之前已经存在, 并且已经被发送(下文会介绍, 时间桶会被作为消息发送到新的Topic
); 这就会导致存在2
个起始时间相同的时间桶, 然而我们却不能将这2
个时间桶合并(因为时间桶带有的c95
,c99
延时等, 不能直接合并).- 该监控,审计工具关注于: 当前时间段内, 我们发送,接收的消息个数以及延时.
- 基于上述原因, 我们用拦截器接收到消息的时间戳计算时间桶.
时间桶用来做什么
在拦截器内, 我们会把得到的时间桶发送到一个新的Kafka Topic
(也可以是新的集群的kafka topic
); 这个Kafka Topic
(之后我把它称为audit topic
)专门用来保存时间桶. 同时启动一个审计应用订阅消费audit topic
数据; 审计应用会解析审计record
, 并将解析后的数据保存到influxdb
内; 这样我们就有了时序数据.
添加看板
配置grafana
, 使用influxdb
作为数据源, 之后就能将时序数据可视化了.
大概的思路就是这样; :)
Thanks!
给上一张使用该工具审计record
的效果图(时间桶间隔5s
, 上面为延时数据, 下面的是消息个数):