自动化测试中如何创建kafka消费者来校验kafka发送的消息内容正确

Kafka自动消费消息软件(自动化测试Kafka) 该C#开发的自动化Kafka消息消费程序为用户提供了一个高效、灵活的Topic消费工具。通过集成Kafka连接配置、Topic自动订阅与消费和日志记录功能,程序能够满足用户在测试和开发过程中对Kafka消息并行消费的需求。Topic消费以及实时日志查看功能进一步增强了程序的功能性和用户体验。 阅读详情
  • kafka工具类:

@Slf4j
public class KafkaUtils {

    public static class KafkaConsumerUtil {

            public KafkaConsumer<String, String> createConsumer(String topic) {
                Properties props = new Properties();
                props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "xxxx.com:39094");
                props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
                props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-group-" + UUID.randomUUID());
                props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
                props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
                props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest");
                props.put("security.protocol", "SASL_PLAINTEXT"); // 根据实际情况选择 SASL_PLAINTEXT/SASL_SSL
                props.put("sasl.mechanism", "PLAIN");
                props.put("sasl.jaas.config",
                        "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"xxx\"" + "password=\"xxxx\";");   // 替换实际密码

                log.info("props是", props);
                KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
                consumer.subscribe(Collections.singletonList(topic));
                consumer.poll(Duration.ZERO); // 触发分区分配
                consumer.seekToEnd(consumer.assignment()); // 定位到末尾
                return consumer;
            }
        }



    }






  • 测试脚本:


@Slf4j
public class MOrderUnfinishedStampUploadPostScenario extends BaseNAFCase {

    private MOrderStampTemplateUploadPost api= new MOrderStampTemplateUploadPost();
    private StampHandCreatePost api2= new StampHandCreatePost();
    File excelFile ;
    String excelFilePath ;
    StampHandCreatePostRequestBody excelBody = new StampHandCreatePostRequestBody();

    @Autowired
    MadeOrderMapper mapper;
    private KafkaUtils.KafkaConsumerUtil kafkaConsumerUtil = new KafkaUtils.KafkaConsumerUtil(); // 直接实例化






    @BeforeMethod
    @Override
    public void initData() {
        // 初始化数据
        // 项目的根目录
        String rootDir = System.getProperty("user.dir");
        // 使用Paths和Path类构建相对路径
        Path relativePath = Paths.get(rootDir)
                .resolve("src/test/resources/case/xx/ExcelData/xx订单.xlsx");

        excelFilePath = relativePath.toString();
        excelFile = new File(excelFilePath);
        // 初始化StampHandCreatePostRequestBody请求参数
        excelBody = new StampHandCreatePostRequestBody();

    }
    // 后置数据库删除
    @AfterMethod
    @Override
    public void tearDown() {
        int i = mapper.deleteTestData();
        log.info("Ω数据库删除列数量>>>>>>>>>>"+i);
        assertEquals(i,4);
    }


    
    @Test(enabled = true,priority = 1)
    public void UploadPost() throws IOException, InterruptedException {
//        新起一个线程,创建一个kafka消费者,用于消费推送的kafka
        Thread thread = new Thread(() -> {
            String topic = "xx";
            KafkaConsumer<String, String> consumer =  kafkaConsumerUtil.createConsumer(topic);
            boolean found = false;
            long timeoutMs = 10000000;
            long startTime = System.currentTimeMillis();
            ObjectMapper mapper = new ObjectMapper();

            try {
                while (System.currentTimeMillis() - startTime < timeoutMs && !found) {
                    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(500));
                    log.info("ConsumerRecords>>>>>>>>>>"+records);
                    for (ConsumerRecord<String, String> record : records) {
                        log.info("Consumed message: Key = {}, Value = {}", record.key(), record.value());
                        JsonNode actualNode = mapper.readTree(record.value());
                        String materialNo = actualNode.get("materialNo").asText();
                        log.info("materialNo是>>>>>>" + materialNo);
//                        校验具体字段
                        assertFiels(materialNo,actualNode,found);

                    }
                }
            } catch (JsonMappingException e) {
                throw new RuntimeException(e);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            } finally {
                consumer.close();
            }
            log.info("found是",found);
            Assert.assertTrue(found, "未找到预期的Kafka消息");
        });
        thread.start();
        Thread.sleep(1000);

//        上传xx文件
        ReadContext f ;
        if (excelFile!=null && excelFile.exists()) {
            // 文件存在,可以进行后续操作
            // 创建HTTP POST请求
            api.addParam("materialType",0);
            f = api.addMultiPart("file", excelFile).asJsonPath();
            HashMap<String,Object> map =f.json();
            // info查看
            log.info("Ω第一次请求状态码>>>>>>>>>"+map.get("code"));
            assertEquals(map.get("code"),200);
            //断言检查

        } else {
            // 文件不存在,处理错误
            throw new IllegalArgumentException("文件不存在: " + excelFilePath);
        }

        // 需要从第一次请求中获取到参数,并作为第二次请求的入参
        // 参数处理
        String json = f.jsonString();
        ObjectMapper objectMapper = new ObjectMapper();

        // 解析JSON字符串为JsonNode对象
        JsonNode rootNode = objectMapper.readTree(json);

        // 从JsonNode中获取"data"字段
        JsonNode dataNode = rootNode.get("data");

        // 从"data"字段中获取"records"数组
        ArrayNode recordsArray = (ArrayNode) dataNode.get("records");

        // 遍历records数组并处理每个元素
        for (JsonNode recordNode : recordsArray) {
            // 在这里处理每个recordNode
            StampHandCreatePostRequestBodyOrderDetailParams orderParams = objectMapper
                    .readValue(recordNode.traverse(), StampHandCreatePostRequestBodyOrderDetailParams.class);
            excelBody.addOrderDetailParamsItem(orderParams);
        }
        excelBody.setMaterialType(1);

        //第二次请求
        ReadContext json2 = api2.setBody(excelBody).asJsonPath();
        //断言检查
        HashMap map=json2.json();
        log.info("Ω第二次请求状态码>>>>>>>>>>"+map.get("code"));
        assertEquals(map.get("code"),200);



    }
    public void assertFiels(String materialNo,JsonNode actualNode,boolean found){
        if ("xxxx".equals(materialNo)) {
            assertEquals(actualNode.get("plantNo").asText(), "xxxx");
            assertEquals(actualNode.get("orderDate").asText(), "2023-05-02");
            assertEquals(actualNode.get("orderType").asText(), "xxxx");
            assertEquals(actualNode.get("quantity").asInt(), 100);
            assertEquals(actualNode.get("orderSerialNo").asText(), "xxxx"");
            assertEquals(actualNode.get("orderReason").asText(), "xxxx");
            assertEquals(actualNode.get("productLineCode").asText(), "xxxx"");
            assertEquals(actualNode.get("productTime").asText(), "xxxx");
            found = true;
            log.info("FCA0100021 found是" + found);
        }
if ("xxxx".equals(materialNo)) {
            assertEquals(actualNode.get("plantNo").asText(), "xxxx");
            assertEquals(actualNode.get("orderDate").asText(), "2023-05-02");
            assertEquals(actualNode.get("orderType").asText(), "xxxx");
            assertEquals(actualNode.get("quantity").asInt(), 100);
            assertEquals(actualNode.get("orderSerialNo").asText(), "xxxx"");
            assertEquals(actualNode.get("orderReason").asText(), "xxxx");
            assertEquals(actualNode.get("productLineCode").asText(), "xxxx"");
            assertEquals(actualNode.get("productTime").asText(), "xxxx");
            found = true;
            log.info("FCA0100021 found是" + found);
        }
        
        else{
            found = false;
        }

    }
}

保姆级教程:用U盘给浪潮服务器装系统(含RAID驱动加载技巧) 本文提供了一份详细的浪潮服务器U盘安装系统指南,重点介绍了RAID驱动加载技巧与实战步骤。从准备工作到系统安装全流程,涵盖RAID配置、驱动加载方法及常见问题排查,帮助用户高效完成服务器系统部署。特别强调RAID驱动与服务器型号的匹配性,确保安装过程顺利。 阅读详情

相关推荐

目标检测技术的发展:从R-CNN、YOLO到DETR、DINO

OV-DINO的出现标志着在开放域目标检测领域的重大进步,其在处理未见过的物体类别时的能力得到了显著提升。这项技术对于需要适应未知或变化环境的应用具有重要意义,如自动驾驶、机器人视觉、安防监控等。

DeepAIedu的博客 2633

消费回调固定 return nil:错误传播与 Kafka 位点提交的区别

Mongo 写入失败时处理器记录错误但不 Mark,外层回调仍返回 nil;返回值与 Kafka 位点提交是不同动作。失败消息是否重投或被后续位点越过,需要结合分区水位分析。

2501_92769340的博客 178

某头部能源集团“数据治理”到“数智应用”跃迁案例剖析

本次案例能源企业实现了从“数据可用”到“指标驱动”再到“智能决策”的全链条升级,标志着集团在数字化、智能化治理能力上的系统跃升,构建起面向未来的数智管理新范式。

a958014226的博客 1258

Kafka 如何实现顺序消费?

Kafka仅保证分区内消息有序,不支持全局有序。实现顺序的关键是:生产端通过相同Key确保消息进入同一分区(配合幂等生产者防重试乱序),消费端保证分区独占且按Key路由至内存队列,由单线程串行处理。吞吐提升可按Key拆分队列并行处理,避免并行导致乱序。核心口诀:同Key同分区,同分区同线程。

217

音频分割:长语音音频 分割为 短语音音频 - python 实现

音频分割:长语音音频 分割为 短语音音频 - python 实现

DATABALL 的博客 1207

Vue3 - Element Plus 表格组件 el-table “表格行数据中又嵌套了二维对象数组“,按平级循环渲染(嵌套数组视为同级行数据), 对嵌套的数组循环展示为表格,智能合并行或列详细教程

vue3,nuxt3,element-plus,table表格组件,el-table,vue3element表格组件,数据中有二维数组怎么遍历循环显示,表格数据带二级数组怎么循环渲染显示,表格数据中存在一个数组要怎么才能显示到表格,el-table表格合并详细教程示例,table表格如果对象里面还有对象数组那该怎么去渲染,平常都是数组中一个对象渲染成一行,每行中还有嵌套数组怎么办,每个行数据下还有一个数组怎么显示,怎么把表格相同的数据合并为一行,合并上下两行相同数据单元格,合并行或列如果遇到相同单元格就合

🏆 前端领域优质创作者 1万+

第十二篇:《完整实战:订单事件驱动系统(Kafka + 消费者 + 死信队列)》

这篇按一条完整的订单链路来搭:订单服务写库 + 发事件,库存服务消费并扣减,失败走指数退避重试,重试耗尽后进入死信队列,消费端全程幂等去重。Outbox 的 relay 是至少一次,DLQ 的重试也是至少一次。重试消费组的 Lag 速率:order-events.retry 的消费 lag 如果持续增长且不回落,说明重试没有收敛,可能正在走向“重试爆炸”的早期形态。retries=MAX_VALUE 配合幂等生产者,解决的是生产者重试导致的 Broker 端重复,不解决消费端业务重复——后者是下一节的事。

qq_45239623的博客 409

在Simulink中构建永磁同步电机的网络化控制模型,并分析通信网络对系统性能的影响

核心优势通过仿真验证了网络延迟和丢包对PMSM控制性能的影响。提供了改进PI参数或引入自适应控制的解决方案。扩展方向抗干扰控制:结合卡尔曼滤波或滑模控制抑制网络噪声。时间敏感网络(TSN)建模:参考知识库[2]的中断触发方式,实现确定性通信。网络安全仿真:模拟恶意攻击(如数据篡改)对控制系统的威胁。

xiaoheshang_123的博客 169

Flink 连接器选型实战:HDFS、Kafka、MySQL 与 Doris 的分层数据架构

连接器选型不是技术炫技,而是对数据特征的准确判断。HDFS承担离线归档与批处理,靠分区和滚动策略控制文件质量。Kafka是实时链路的中枢,靠分区、攒批和事务保证吞吐与一致性。MySQL只做维表和小结果集,靠缓存和限流保护在线库。Doris承接大数据量分析写入,靠分桶、攒批和两阶段提交保证性能与准确。把这四者按数据规模、延迟要求和一致性要求分层组合,就能搭出一套既稳定又可扩展的 Flink 数据架构。

2401_83857914的博客 849

YOLOv8中的可变形卷积改进 | 从DCNv1到DCNv3的多位置替换可变形卷积保姆级实操

可变形卷积(Deformable Convolution)最早由Dai等人在2017年提出,其核心思想是在标准卷积操作的基础上,引入可学习的偏移量(offsets),使卷积核能够自适应调整其采样位置,从而增强模型对目标变形的感知能力。return x本文通过深入探讨可变形卷积在YOLOv8中的应用,详细介绍了DCNv1、DCNv2和DCNv3的原理和实现,并通过实验验证了其在目标检测任务中的有效性。未来,我们将继续探索更多优化策略和技术,提升YOLOv8模型的性能,以应对更复杂的目标检测任务。

一键难忘的博客 4051

基于STM32L4XX、HAL库的MCP4561数字电位器驱动程序设计

/ HAL库需要左移一位。* @param address: 设备地址(0x2C-0x2F)* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hmcp: MCP4561句柄。* @param hi2c: I2C句柄。

zhusl6688的博客 341

Kafka 的存储也能进对象存储:用 AutoMQ 把日志流写进 RustFS

Kafka 的痛点是存储和 broker 绑死在一起。topic 一多、留存一久,broker 本地盘就被日志段塞满,扩容不是加 broker 就是换更大的盘,数据还得在节点间搬来搬去。更麻烦的是 broker 一旦挂了,恢复全靠副本在别的节点重建,磁盘 IO 先爆一轮。AutoMQ 是 Kafka 的一个云原生发行版,思路是把存储和 broker 彻底解耦:预写日志先在本地缓冲,随后作为不可变…

分布式存储与RustFS的博客 329

猿创征文|Qt 文件和目录应用讲解【QCoreApplication】【QFile、QFileInfo】【QTemporaryDir和QTemporaryFile】【QDir】【QFileSyste】

Qt 文件和目录精准讲解【QCoreApplication】【QFile、QFileInfo】【QTemporaryDir和QTemporaryFile】【QDir】【QFileSyste】【QFileDialog】 第一章 QCoreApplication类 第一节 QCoreApplication常用函数方法 第二节 QCoreApplication举例 第二章 QFile类 第一节 静态函数方法 第二节 成员函数方法 第三章 QFileInfo类 第一节 常用函数方法 第四章 QDir类

Qt历险记,专注Qt技术,三年医疗设备研发经验,1年机器视觉研发经验,半年柔性传感研发经验。 943

Kafka 中 Zookeeper 的作用?

老版Kafka依赖ZooKeeper实现分布式协调,利用其临时节点和Watcher机制完成Broker注册、Controller选举、元数据存储及消费者组管理。但ZK带来运维复杂、性能瓶颈与容量限制。自Kafka 2.8引入KRaft协议,以内置Raft共识取代ZK,将元数据存于__cluster_metadata主题,实现更高效、易维护的元数据管理,3.5版本起正式废弃ZK模式。

angel_tor的专栏 215

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【Kafka 从入门到实战】从手写一个队列到生产级消息中间件:架构、分区、消费组、零拷贝全解析

本文从队列基础出发,层层解析Kafka架构与设计精髓,涵盖消息队列本质、核心术语、分区机制、生产者消费者模型及四大性能优化原理:顺序写入、批量压缩、页缓存、零拷贝。附完整可运行Python代码(建Topic、生产/消费),并总结12道高频面试题与踩坑记录,帮助读者真正理解Kafka“为何快”,而非仅背“零拷贝”一词。

wiwiwiwiooo的博客 345

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

从0到1掌握Kafka与RabbitMQ在IM即时聊天中的

本文从理论出发,结合《Designing Data-Intensive Applications》一书的知识体系,通过实际代码演示了如何利用Kafka与RabbitMQ来支撑IM系统的不同模块。无论是私聊还是群聊场景都可以找到对应解决方案。接下来你可以尝试以下几个方向进行深入学习: 1. 实现多节点集群部署,并了解如何设置HA机制。2. 学习如何在Spring Boot等框架中整合这两种中间件。3. 探索使用Flink或Spark Streaming对接Kafka做实时分析。

qq_41106321的博客 210

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

只 Mark 最后一条:Kafka 跨分区消费水位的风险

历史快照中两个分区重启后 lag 为 1;当前批次回调只 Mark 最后一条,可能漏记其他分区的进度,但快照不足以证明永久停滞或唯一根因。

2501_92769340的博客 191

第九篇:《Kafka 监控与运维:Lag、Under-replicated Partition 与磁盘管理》

标签:Kafka | 监控 | Consumer Lag | Under-replicated Partition | 磁盘管理 | 运维 | SRE适合人群:负责 Kafka 集群稳定性的 SRE、后端开发,被“告警响了但不知道要不要起床”折磨过的同学阅读收益:搞清楚 Lag 告警为什么用绝对值会双向失效、URP 为什么不能一看到就重启、磁盘管理为什么“百分比告警”是错的,以及三条可以直接抄的运维规则前言:凌晨两点的两个告警,一个误报,一个差点搞出大事故先说两个真实场景。

qq_45239623的博客 478

第十篇:《Kafka 安全加固:SASL、SSL、ACL 与多租户隔离》

allow.everyone.if.no.acl.found 的生产语义必须理解清楚:默认 false 是安全的选择——如果一个资源没有任何 ACL,除了超级用户,谁都无权访问。最关键、也最容易被误解的语义是:配额是按 Broker 强制的,不是按集群强制的。另一个静默坑是后缀与格式不匹配:给 PKCS12 格式的密钥库文件用了 .jks 后缀,部分 Spring Boot 版本的 SSL 类型自动探测会按 JKS 格式加载,失败后直接返回空密钥库,启动时不抛异常,只在握手时表现为没有证书。

qq_45239623的博客 322

Kafka 消费者每 5 分钟触发一次 Rebalance,把 max.poll.interval.ms 调大仍然掉线

消费者加入消费组后每约 5 分钟被踢出一次。文中命令与代码块可直接复制执行,未实测的结论均已单独标注。文中给出了可复现的环境与操作步骤,并标注了哪些结论已经验证、哪些仍属推测。

昨日种种,皆成今我。今日种种,皆成新我。 190

第二篇:《CommitLog + ConsumeQueue:一条日志解决 Kafka 多分区随机写的难题》

RocketMQ 采用 CommitLog 全局顺序写 + ConsumeQueue 索引的存储模型,解决 Kafka 多 Topic 场景下跨 Partition 随机写问题。CommitLog 存所有消息,保证写入顺序;ConsumeQueue 为每 Topic+Queue 的 20 字节索引(偏移量、长度、Tag 哈希),支持消费者“读两次”定位消息。虽有读放大与异步重建代价,但通过顺序写与 mmap 零拷贝实现高性能,本质是用索引换写入可扩展性。

qq_45239623的博客 262

消息队列入门:RabbitMQ 与 Kafka 核心概念与运维要点

BIOS→GRUB→内核→systemd→target 全链路解读,root 密码忘了解锁、文件系统损坏修复、单用户模式与救援模式实战,服务器起不来时的救命指南。

2502_91473995的博客 400

ubuntu安装kafka

搭建基于KRaft模式的Kafka三节点集群,使用Kafka 3.9.1与Java 11,三台机器(master、worker1、worker2)各承担broker与controller角色。通过统一集群ID初始化,配置节点ID与监听地址,分发配置并设置环境变量。启动后通过命令行创建主题、测试消息收发,验证集群正常运行。无需ZooKeeper,适合实验环境。日常启停需在每台执行对应脚本。

qq_43592674的博客 214

Kafka消息可靠性问题全景

Kafka 消息可靠性不是靠单一配置解决的,而是 Producer(acks+幂等)→ Broker(副本+ISR)→ Consumer(手动提交+幂等处理)三层防线协同。追求零丢失必然带来重复,追求严格顺序必然牺牲并行度——根据业务容忍度做取舍才是正解。

qq_39883927的博客 129

Kafka 如何保证消息不丢失?

Kafka消息丢失仅发生在生产、存储、消费三环节。防丢需“三端三手”:生产者用acks=all+重试+回调,确保发送可靠;Broker配置replication.factor>=3、min.insync.replicas>=2、禁用脏选举,保障副本同步;消费者关闭自动提交,手动提交offset,先处理后提交。核心逻辑:发得稳、存得牢、提得晚。追问点包括参数联动(如acks与min.insync)、幂等性与重复消费权衡,体现真实生产经验。

367

kafka常见问题汇总

按「现象 → 定位 → 处理」整理。

qq_38636133的博客 308
上一篇: 微信开发者工具使用
下一篇: jmeter如何让一个线程组中的多个请求同时触发
sssammmm
博客等级 码龄9年 369粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值