Strimzi Kafka Bridge(桥接)实战之二:生产和发送消息
欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
本文是《Strimzi Kafka Bridge(桥接)实战之》系列的第二篇,咱们直奔bridge的重点:常用接口,用实际操作体验如何用bridge完成常用的消息收发业务
官方的openapi接口文档地址 : https://strimzi.io/docs/bridge/in-development/#_openapi
整篇文章由以下内容构成:
- 准备工作:创建topic
- 生产消息
- 消费消息,strimzi bridge消费消息的逻辑略有些特殊,就是要提前创建strimzi bridge consumer,再通过consumer来调用拉取消息的接口
- 完成本篇实战后,相信您已经可以数量的通过http来使用kafka的服务了
准备工作:创建topic
- 遗憾的是,bridge未提供创建topic的API,所以咱们还是用命令来创建吧
- ssh登录kubernetes的宿主机
- 执行创建名为bridge-quickstart-topic的topic,共四个分区
kubectl -n aabbcc \
run kafka-producer \
-ti \
--image=quay.io/strimzi/kafka:0.32.0-kafka-3.3.1 \
--rm=true \
--restart=Never \
-- bin/kafka-topics.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--create \
--topic bridge-quickstart-topic \
--partitions 4 \
--replication-factor 1
- 检查topic创建是否成功
kubectl -n aabbcc \
run kafka-producer \
-ti \
--image=quay.io/strimzi/kafka:0.32.0-kafka-3.3.1 \
--rm=true \
--restart=Never \
-- bin/kafka-topics.sh \
--bootstrap-server my-cluster-kafka-bootstrap:9092 \
--describe \
--topic bridge-quickstart-topic
- 如下图,可见topic的创建符合预期
- 接下来的操作都是向bridge发送http请求完成的,我这边宿主机的IP地址是192.168.0.1,bridge的NodePort端口号31331
查看指定topic的详情
- 如下请求,可以取得topicbridge-quickstart-topic的详情
curl -X GET \
http://192.168.0.1:31331/topics/bridge-quickstart-topic
- 收到响应如下,是这个topic的详细信息
{
"name": "bridge-quickstart-topic",
"configs": {
"compression.type": "producer",
"leader.replication.throttled.replicas": "",
"message.downconversion.enable": "true",
"min.insync.replicas": "1",
"segment.jitter.ms": "0",
"cleanup.policy": "delete",
"flush.ms": "9223372036854775807",
"follower.replication.throttled.replicas": "",
"segment.bytes": "1073741824",
"retention.ms": "604800000",
"flush.messages": "9223372036854775807",
"message.format.version": "3.0-IV1",
"max.compaction.lag.ms": "9223372036854775807",
"file.delete.delay.ms": "60000",
"max.message.bytes": "1048588",
"min.compaction.lag.ms": "0",
"message.timestamp.type": "CreateTime",
"preallocate": "false",
"min.cleanable.dirty.ratio": "0.5",
"index.interval.bytes": "4096",
"unclean.leader.election.enable": "false",
"retention.bytes": "-1",
"delete.retention.ms": "86400000",
"segment.ms": "604800000",
"message.timestamp.difference.max.ms": "9223372036854775807",
"segment.index.bytes": "10485760"
},
"partitions": [
{
"partition": 0,
"leader": 0,
"replicas": [
{
"broker": 0,
"leader": true,
"in_sync": true
}
]
},
{
"partition": 1,
"leader": 0,
"replicas": [
{
"broker": 0,
"leader": true,
"in_sync": true
}
]
},
{
"partition": 2,
"leader": 0,
"replicas": [
{
"broker": 0,
"leader": true,
"in_sync": true
}
]
},
{
"partition": 3,
"leader": 0,
"replicas": [
{
"broker": 0,
"leader": true,
"in_sync": true
}
]
}
]
}
批量生产消息(同步)
- 试试bridge提供的批量生产消息的API,以下命令会生产了三条消息,第一条通过key的hash值确定分区,第二条用partition参数明确指定了分区是2,第三条的分区是按照轮询策略更新的
curl -X POST \
http://42.193.162.141:31331/topics/bridge-quickstart-topic \
-H 'content-type: application/vnd.kafka.json.v2+json' \
-d '{
"records": [
{
"key": "my-key",
"value": "sales-lead-0001"
},
{
"value": "sales-lead-0002",
"partition": 2
},
{
"value": "sales-lead-0003"
}
]
}'
- bridge响应如下,会返回每一条消息的partition和offset,这就是同步消息的特点,等到meta信息更新完毕后才会返回
{
"offsets": [{
"partition": 0,
"offset": 0
}, {
"partition": 2,
"offset": 0
}, {
"partition": 3,
"offset": 0
}]
}
批量生产消息(异步)
- 有的场景下,例如追求高QPS并且对返回的meta信息不关注,可以考虑异步的方式发送消息,也就是说bridge收到响应后立即返回200,这种异步模式和前面的同步模式只有一个参数的差别:在请求url中增加async=true即可
curl -X POST \
http://42.193.162.141:31331/topics/bridge-quickstart-topic?async=true \
-H 'content-type: application/vnd.kafka.json.v2+json' \
-d '{
"records": [
{
"key": "my-key",
"value": "sales-lead-0001"
},
{
"value": "sales-lead-0002",
"partition": 2
},
{
"value": "sales-lead-0003"
}
]
}'
- 没有响应body,请您自行请求感受一下,响应明显比同步模式快
查看partition
- 查看tipic的parition情况
curl -X GET \
http://42.193.162.141:31331/topics/bridge-quickstart-topic/partitions
- 响应
[{
"partition": 0,
"leader": 0,
"replicas": [{
"broker": 0,
"leader": true,
"in_sync": true
}]
}, {
"partition": 1,
"leader": 0,
"replicas": [{
"broker": 0,
"leader": true,
"in_sync": true
}]
}, {
"partition": 2,
"leader": 0,
"replicas": [{
"broker": 0,
"leader": true,
"in_sync": true
}]
}, {
"partition": 3,
"leader": 0,
"replicas": [{
"broker": 0,
"leader": true,
"in_sync": true
}]
}]
- 查看指定partition
curl -X GET \
http://42.193.162.141:31331/topics/bridge-quickstart-topic/partitions/0
- 响应
{
"partition": 0,
"leader": 0,
"replicas": [{
"broker": 0,
"leader": true,
"in_sync": true
}]
}
- 查看指定partition的offset情况
curl -X GET \
http://42.193.162.141:31331/topics/bridge-quickstart-topic/partitions/0/offsets
- 响应
{
"beginning_offset": 0,
"end_offset": 5
}
创建bridge consumer
- 通过bridge消费消息,有个特别且重要的前提:创建bridge consumer,只有先创建了bridge consumer,才能顺利从kafka的broker取到消息
- 以下命令创建了一个bridge consumer,各参数的含义稍后会说明
curl -X POST http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group \
-H 'content-type: application/vnd.kafka.v2+json' \
-d '{
"name": "bridge-quickstart-consumer",
"auto.offset.reset": "earliest",
"format": "json",
"enable.auto.commit": false,
"fetch.min.bytes": 16,
"consumer.request.timeout.ms": 300000
}'
- 上述请求的参数解释:
- 对应kafka的group为bridge-quickstart-consumer-group
- 此bridge consumer的name等于bridge-quickstart-consumer
- 参数enable.auto.commit表示是否自动提交offset,这里设置成false,表示无需自动提交,后面的操作中会调用API请求来更新offset
- 参数fetch.min.bytes要特别注意,其值等于16,表示唯有消息内容攒够了16字节,拉取消息的请求才能获取到消息,如果消息内容长度不到16字节,收到的响应body就是空
- 参数consumer.request.timeout.ms也要注意,这里我设置了300秒,如果超过300秒没有去拉取消息,这个消费者就会被kafka移除(被移除后如果再去拉取消息,kafka会报错:Offset commit cannot be completed since the consumer is not part of an active group for auto partition assignment; it is likely that the consumer was kicked out of the grou)
- 收到响应如下,instance_id表示这个bridge consumer的身份id,base_uri则是订阅消息时必须使用的请求地址
{
"instance_id": "bridge-quickstart-consumer",
"base_uri": "http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer"
}
如何删除bridge consumer
- 以下命令可以删除consumer,重点是将身份id放入path中
curl -X DELETE http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer
订阅指定topic的消息
- 创建bridge consumer成功后,接下来就能以这个consumer的身份去订阅kafka消息了
- 执行以下命令可以订阅topic为bridge-quickstart-topic的kafka消息,注意请求地址就是前面创建bridge consumer时返回的base_uri字段
curl -X POST http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer/subscription \
-H 'content-type: application/vnd.kafka.v2+json' \
-d '{
"topics": [
"bridge-quickstart-topic"
]
}'
- 从上述请求body可以看出,此请求可以一次订阅多个topic,而且还可以使用topic_pattern(正则表达式)的形式来一次订阅多个topic
- 订阅完成后,接下来就能主动拉取消息了
拉取消息
- 在拉取消息之前,请确保已经提前生产了消息
- 执行以下命令拉取一条消息
curl -X GET http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer/records \
-H 'accept: application/vnd.kafka.json.v2+json'
- 然而,当您执行了上述命令后,会发现返回body为空,别担心,这是正常的现象,按照官方的说法,拉取到的第一条消息就是空的,这是因为拉取操作出触发了rebalancing逻辑(rebalancing是kafka的概览,是处理多个partition消费的操作),再次执行上述命令去拉取消息,这下正常了,body如下
[
{
"topic": "bridge-quickstart-topic",
"key": "my-key",
"value": "sales-lead-0001",
"partition": 0,
"offset": 0
}, {
"topic": "bridge-quickstart-topic",
"key": "my-key",
"value": "sales-lead-0001",
"partition": 0,
"offset": 1
}
]
提交offset
- 前面在创建bridge consumer的时候,参数enable.auto.commit的值等于fasle,表示由调用方主动提交offset到kafka,因此在拉取到消息之后,需要手动更新kafka consumer的offset
curl -X POST http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer/offsets
- 该请求无返回body,只要返回码是204就表示成功
设定offset
- 试想这样的场景:共生产了100条消息,消费者也已经将这100条全部消费完毕,现在由于某种原因,需要从91条开始,重新消费91-100这10条消息(例如需要重新计算),此时可以主动设定offset
- 先执行以下命令,生产一条消息
curl -X POST \
http://42.193.162.141:31331/topics/bridge-quickstart-topic \
-H 'content-type: application/vnd.kafka.json.v2+json' \
-d '{
"records": [
{
"value": "sales-lead-a002-01234567890123456789",
"partition": 2
}
]
}'
- 如下图红色箭头,可见当前partition已经生产了75条消息了
- 咱们先拉取消息,将消息都消费掉
- 由于没有新生产消息,此时再拉去应该拉取不到了
- 现在执行以下请求,就可以将offset设置到74
curl -X POST http://42.193.162.141:31331/consumers/bridge-quickstart-consumer-group/instances/bridge-quickstart-consumer/positions \
-H 'content-type: application/vnd.kafka.v2+json' \
-d '{
"offsets": [
{
"topic": "bridge-quickstart-topic",
"partition": 2,
"offset": 74
}
]
}'
- 再次拉取消息,发现74和之后的所有消息都可以拉去到了(注意,包含了74)
- 至此,咱们对生产和发送消息的常用接口都已经操作了一遍,对于常规的业务场景已经够用,接下来的文章,咱们以此为基础,玩出更多花样来
欢迎关注博客园:程序员欣宸
Strimzi Kafka Bridge(桥接)实战之二:生产和发送消息的更多相关文章
- RabbitMQ学习系列二-C#代码发送消息
RabbitMQ学习系列二:.net 环境下 C#代码使用 RabbitMQ 消息队列 http://www.80iter.com/blog/1437455520862503 上一篇已经讲了Rabbi ...
- Kafka发送消息失败原因
Kafka发送消息方法如下: Properties properties = new Properties(); properties.put("zookeeper.connect" ...
- Kafka学习笔记(6)----Kafka使用Producer发送消息
1. Kafka的Producer 不论将kafka作为什么样的用途,都少不了的向Broker发送数据或接受数据,Producer就是用于向Kafka发送数据.如下: 2. 添加依赖 pom.xml文 ...
- Flink的sink实战之二:kafka
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Zookeeper+Kafka完全分布式实战部署
Zookeeper+Kafka完全分布式实战部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实我之前部署过kafak和zookeeper的完全分布式,集群是可以正常使用没错, ...
- Kafka ACL使用实战(单机版)
一.简介 自0.9.0.0.版本引入Security之后,Kafka一直在完善security的功能.当前Kafka security主要包含3大功能:认证(authentication).信道加密( ...
- [转帖]Kafka 原理和实战
Kafka 原理和实战 https://segmentfault.com/a/1190000020120043 两个小时读完... 实在是看不完... 1.2k 次阅读 · 读完需要 101 分钟 ...
- kafka原理和实践(二)spring-kafka简单实践
系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...
- zookeeper+kafka集群安装之二
zookeeper+kafka集群安装之二 此为上一篇文章的续篇, kafka安装需要依赖zookeeper, 本文与上一篇文章都是真正分布式安装配置, 可以直接用于生产环境. zookeeper安装 ...
- Mybaits-plus实战(二)
1. Mybaits-plus实战(二) 1.1. mybatis-plus插件 1.1.1. 用法 先举个例子介绍用法,如下:直接作为Bean注入,一般来讲插件太多印象性能,所以大部分插件都只在测试 ...
随机推荐
- 算法基础(一):串匹配问题(BF,KMP算法)
好家伙,学算法, 这篇看完,如果没有学会KMP算法,麻烦给我点踩 希望你能拿起纸和笔,一边阅读一边思考,看完这篇文章大概需要(20分钟的时间) 我们学这个算法是为了解决串匹配的问题 那什么是串匹配 ...
- 解密Prompt系列9. 模型复杂推理-思维链COT基础和进阶玩法
终于写了一篇和系列标题沾边的博客,这一篇真的是解密prompt!我们会讨论下思维链(chain-of-Thought)提示词究竟要如何写,如何写的更高级.COT其实是Self-ASK,ReACT等利用 ...
- Java使用redis-Redis是并发安全的吗?
大家都清楚,Redis 是一个开源的高性能键值对存储系统,被开发者广泛应用于缓存.消息队列.排行榜.计数器等场景.由于其高效的读写性能和丰富的数据类型,Redis 受到了越来越多开发者的青睐.然而,在 ...
- 我在使用Winform7.0开发海康相机应用的时候系统悄无声息的退出
一.简介 1.说明一下 最近,我在开发一个玻璃幕墙检测的项目,这个项目需要使用到海康的相机系统.业务是这样的,相机按着指定的坐标,扫描玻璃幕墙的每块玻璃,通过算法查看是否有损坏的,如果有就发出报警信息 ...
- SQL SERVER 拼接字符串转化为表结构数据
本文为一些需要对特殊符号分隔的字符串进行解析,比如将 select '10,20,30,40,50,60' 这个字符串转化为一列多行 下面提供源代码: 1 SET QUOTED_IDENTIFIER ...
- QOJ 6504. CCPC Final 2022 D Flower's Land 2题解
QOJ 6504. CCPC Final 2022 D Flower's Land 2题解 题意简述 给你一个只含 \(0,1,2\) 的序列,相邻两个相同的数字可以直接消掉. 询问包含两种 区间所有 ...
- 《架构整洁之道》学习笔记 Part 2 编程范式
计算机编程发展至今,一共只有三个编程范式: 结构化编程 面向对象编程 函数式编程 编程范式和软件架构的关系 结构化编程是各个模块的算法实现基础 多态(面向对象编程)是跨越架构边界的手段 函数式编程是规 ...
- PWM点灯
目录 PWM脉冲宽调点灯 前言 1.什么是PWM 2.PWM的实现 3.PWM实现步骤(通用定时器) 3.1 打开定时器的时钟 3.2 配置端口 3.3 设置定时器 3.4 设置PWM 3.5 完整代 ...
- linux top中 VSS,RSS,PSS,USS 4个字段的解读
参考文章:linux中top命令 VSS,RSS,PSS,USS 四个内存字段的解读
- 浏览器端模块化方式es module详解
在es module出现之前还有社区推出amd和cmd的规范,这两者还有其特定的编写方式,使用起来不算很方便.es module被官方推出来就成为了浏览器端实现模块化的一个很好的方案. 想要在浏览 ...