使用 Testcontainers 在 JUnit 测试中启动 Redpanda:完整配置、安全认证与多监听器实战指南

发布时间:2026/11/11 13:54:31

使用 Testcontainers 在 JUnit 测试中启动 Redpanda:完整配置、安全认证与多监听器实战指南 使用 Testcontainers 在 JUnit 测试中启动 Redpanda完整配置、安全认证与多监听器实战指南【免费下载链接】testcontainers-javaTestcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.项目地址: https://gitcode.com/GitHub_Trending/te/testcontainers-javaTestcontainers 的testcontainers-redpanda模块可以在测试中自动实例化并管理 Redpanda 容器让开发者无需在本地搭建 Kafka 兼容环境即可完成消息队列、Schema Registry 与安全认证相关功能的集成测试。读完本文你将掌握 Redpanda 容器的创建与启动、Bootstrap Servers 与 Schema Registry 地址的获取、SASL/Authorization/Superuser 安全配置、AdminClient 的创建以及如何通过注册额外监听器让同网络容器或外部代理进程如 Toxiproxy连接 Redpanda。模块概述官方镜像与默认端口Testcontainers 使用 Redpanda 官方 Docker 镜像docker.redpanda.com/redpandadata/redpanda或redpandadata/redpanda来实例化 Redpanda 容器模块依赖镜像中提供的内置功能完成启动与配置注入。从 RedpandaContainer.java 的源码可见容器默认暴露以下四个端口端口用途9092BrokerKafka 兼容协议入口9644Redpanda Admin API8081Schema Registry8082REST ProxyPandaproxy镜像版本方面模块要求 Redpanda 版本必须不低于 v22.2.1。源码中通过ComparableVersion对镜像版本进行校验若传入更早版本会抛出IllegalArgumentException(Redpanda version must be v22.2.1)测试 RedpandaContainerTest.java 与 CompatibleImageTest.java 均验证了这一约束。容器启动时模块会以root:root用户、以--modedev-container --smp1 --memory1G参数运行redpanda start并等待日志中出现Successfully started Redpanda!才判定就绪见RedpandaContainer构造函数。同时它会将 classpath 资源testcontainers/entrypoint-tc.sh等待注入配置完成后才转发给官方入口脚本以及由 FreeMarker 模板bootstrap.yaml.ftl、redpanda.yaml.ftl渲染生成的配置文件分别复制到容器/etc/redpanda/下。最小示例创建容器并连接 Kafka 客户端创建RedpandaContainer并启动它即可在测试中使用代码示例如下取自 RedpandaContainerTest.java// constructorWithVersion { RedpandaContainer container new RedpandaContainer(docker.redpanda.com/redpandadata/redpanda:v23.1.2) // }容器支持传入字符串形式的完整镜像名也支持DockerImageName对象。启动后运行在本机或同一测试进程的任意客户端可通过如下方式获得 Broker 连接地址// getBootstrapServers { container.getBootstrapServers() // }getBootstrapServers()返回形如PLAINTEXT://host:mappedPort的地址其中 host 与端口由容器实际映射决定确保本机进程可以直接访问。模块同时提供其他地址获取方法getSchemaRegistryAddress()返回http://host:mappedPort8081 端口用于 Schema Registry 客户端。getAdminAddress()返回http://host:mappedPort9644 端口用于调用 Redpanda Admin API。getRestProxyAddress()返回http://host:mappedPort8082 端口用于 REST Proxy 的 HTTP 访问。验证完整消息链路抽象测试基类 AbstractRedpanda.java 展示了一条完整的“建 Topic → 生产 → 消费”链路使用 KafkaAdminClient创建NewTopic用KafkaProducer发送(testcontainers, rulezzz)消息再通过KafkaConsumerauto.offset.resetearliest在 10 秒内轮询并断言消息完整到达。这说明 Redpanda 与 Kafka 客户端协议完全兼容现有 Kafka 生态工具生产者、消费者、AdminClient无需修改即可复用。使用 Schema RegistryRedpanda 提供了 Schema Registry 实现地址同样由容器映射动态生成// getSchemaRegistryAddress { container.getSchemaRegistryAddress() // }测试 RedpandaContainerTest.java 使用 RestAssured 通过该地址调用/subjects与/subjects/{subject}/versions接口注册并查询 schema验证了 Schema Registry 的完整读写能力。启用安全特性授权、SASL 与超级用户模块支持在测试中一键开启 Redpanda 的安全能力通过链式方法组合使用// security { RedpandaContainer redpanda new RedpandaContainer(docker.redpanda.com/redpandadata/redpanda:v23.1.7) .enableAuthorization() .enableSasl() .withSuperuser(superuser-1) // }三个核心方法见 RedpandaContainer.java说明如下方法作用底层效果enableAuthorization()开启 Kafka API 授权在渲染bootstrap.yaml.ftl时写入kafka_enable_authorization: true并影响内部监听器的认证方式enableSasl()开启 SASL 认证将authenticationMethod置为sasl注入到 Kafka API 与 Schema Registry 的配置中withSuperuser(String username)注册超级用户将用户名写入bootstrap.yaml.ftl的superusers列表该用户可绕过授权检查此外模块还提供enableSchemaRegistryHttpBasicAuth()为 Schema Registry 开启 HTTP Basic 认证对应测试schemaRegistryWithHttpBasic未认证访问返回 401携带超级用户 Basic 凭据后返回 200。创建用户与 AdminClient开启 SASL 后需要通过 Redpanda Admin API 创建用户再构造携带凭据的 KafkaAdminClientprivate void createSuperUser(RedpandaContainer redpanda) { String adminUrl String.format(%s/v1/security/users, redpanda.getAdminAddress()); RestAssured .given() .contentType(application/json) .body({\username\: \superuser-1\, \password\: \test\, \algorithm\: \SCRAM-SHA-256\}) .post(adminUrl) .then() .statusCode(200); } // createAdminClient { AdminClient adminClient AdminClient.create( ImmutableMap.of( AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer, AdminClientConfig.SECURITY_PROTOCOL_CONFIG, SASL_PLAINTEXT, SaslConfigs.SASL_MECHANISM, SCRAM-SHA-256, SaslConfigs.SASL_JAAS_CONFIG, org.apache.kafka.common.security.scram.ScramLoginModule required username\superuser-1\ password\test\; ) ); // }注意bootstrapServer由redpanda.getHost() : redpanda.getMappedPort(9092)拼出。测试 RedpandaContainerTest.java 还验证了三种安全场景超级用户建 Topic 成功、非授权用户建 Topic 抛出TopicAuthorizationException、未认证访问抛出SaslAuthenticationException可用于编写安全回归测试时对照预期行为。注册额外监听器连接同网络容器默认情况下Redpanda 容器对外暴露的端口是9092其监听器地址advertised listener指向宿主机映射端口。但存在两类场景需要额外监听器消费者/生产者是同一 Docker 网络中的另一个容器此时外部映射端口在容器网络内不可用需要以容器网络别名访问连接端口与默认暴露端口不同的进程例如通过 Toxiproxy 模拟网络故障时客户端实际连接的是代理端口。模块通过withListener系列方法支持注册额外监听器。首先看“同网络容器”场景注册监听器// registerListener { RedpandaContainer kafka new RedpandaContainer(docker.redpanda.com/redpandadata/redpanda:v23.1.7) .withListener(kafka:19092) .withNetwork(network); // }再创建同一网络内的 kcat 容器// createKCatContainer { GenericContainer? kcat new GenericContainer(confluentinc/cp-kcat:7.9.0) .withCreateContainerCmdModifier(cmd - { cmd.withEntrypoint(sh); }) .withCopyToContainer(Transferable.of(Message produced by kcat), /data/msgs.txt) .withNetwork(network) .withCommand(-c, tail -f /dev/null) // }客户端使用新注册的监听器地址kafka:19092完成生产与消费// produceConsumeMessage { kcat.execInContainer(kcat, -b, kafka:19092, -t, msgs, -P, -l, /data/msgs.txt); String stdout kcat .execInContainer(kcat, -b, kafka:19092, -C, -t, msgs, -c, 1) .getStdout(); // }实现原理在 RedpandaContainer.java 的configure()中注册监听器的主机名会被加入网络别名network alias同时渲染redpanda.yaml.ftl时会把这些监听器追加到kafka_api与advertised_kafka_api列表。默认的监听器配置为默认监听器listeners0.0.0.0:9092external、0.0.0.0:9093internal供 Schema Registry / Pandaproxy 客户端在容器内使用默认广告监听器advertised listenerscontainerHost:mappedPort(9092)、127.0.0.1:9093。redpanda.yaml.ftl中还固定了 Admin API9644、Schema Registry8081、Pandaproxy8082的监听地址以及rpk默认连接的localhost:9093保证容器内部工具开箱即用。通过代理注册监听器外部进程访问场景当客户端运行在容器网络之外、且连接端口与默认映射端口不一致时可以注册一个“监听器 广告监听器”的组合。官方文档以SocatContainer作为代理为例。首先创建代理容器将宿主机某端口转发到容器网络内的kafka:19092// createProxy { SocatContainer socat new SocatContainer().withNetwork(network).withTarget(2000, kafka, 19092); // }随后注册监听器与广告监听器// registerListenerAndAdvertisedListener { RedpandaContainer kafka new RedpandaContainer(docker.redpanda.com/redpandadata/redpanda:v23.1.7) .withListener(kafka:19092, () - socat.getHost() : socat.getMappedPort(2000)) .withNetwork(network) // }此时 Kafka 客户端实际通过代理地址连接并完成完整消息链路验证// produceConsumeMessageFromProxy { String bootstrapServers String.format(%s:%s, socat.getHost(), socat.getMappedPort(2000)); testKafkaFunctionality(bootstrapServers); // }withListener(String listener, SupplierString advertisedListener)的语义是listener格式host:port注册为容器内实际监听端点其 host 同时成为网络别名advertisedListener则通过Supplier动态计算因为此时容器端口尚未映射完成客户端会根据广告监听器地址去连接从而实现“容器内监听 网络外代理访问”的完整链路。这对构造故障注入如 Toxiproxy或流量代理测试非常有用。兼容性说明源码中还有一个Deprecated的withListener(SupplierString)旧接口新代码应使用上述字符串/Supplier 组合形式withListener(String)与withListener(String, SupplierString)。添加模块依赖在项目中引入testcontainers-redpanda模块{{latest_version}}请替换为实际使用的版本号 GradletestImplementation org.testcontainers:testcontainers-redpanda:{{latest_version}} Mavendependency groupIdorg.testcontainers/groupId artifactIdtestcontainers-redpanda/artifactId version{{latest_version}}/version scopetest/scope /dependency与 Testcontainers 其他模块一致该模块仅需声明为测试依赖即可运行测试前请确保当前环境已具备 Docker 可用条件参见仓库根目录 README.md 与环境要求说明。实战要点小结版本下限Redpanda 镜像版本必须 ≥ v22.2.1否则模块直接拒绝启动并抛出IllegalArgumentException。端口规划9092Broker、9644Admin、8081Schema Registry、8082REST Proxy均已默认暴露并注入对应配置。安全组合enableAuthorization()enableSasl()withSuperuser(...)可一键构建带认证与授权的集群用户创建走 Admin API/v1/security/users客户端需携带 SCRAM-SHA-256 凭据。多监听器同网络容器用withListener(host:port)自动注册网络别名外部代理场景用withListener(host:port, supplier)提供动态广告监听器地址。配置注入机制模块通过 FreeMarker 模板redpanda.yaml.ftl、bootstrap.yaml.ftl在容器启动时生成配置文件并借助 entrypoint-tc.sh 等待配置就绪后再启动 Redpanda 主进程确保端口映射已知且配置一致。以上所有用法均可在仓库测试中找到可运行的完整示例建议结合 RedpandaContainerTest.java 与 CompatibleImageTest.java 进一步阅读验证。【免费下载链接】testcontainers-javaTestcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.项目地址: https://gitcode.com/GitHub_Trending/te/testcontainers-java创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/4 6:36:01

从爬虫到Spark再到ECharts:豆瓣电影数据分析全流程实践

简介:一份基于豆瓣电影爬虫与Spark数据分析可视化的毕业设计源码包,面向计算机相关专业的在校学生、教师或大数据入门者,尤其适合作为毕设课题、课程设计或项目初期演示的参考模板,内容围绕“爬虫采集—数据清洗—Spark分析—可视…

2026/11/4 9:40:03

PyTorch GPU/CPU设备调度:单卡、多卡训练与模型保存加载全指南

1. 为什么这个总结值得你花15分钟认真读完PyTorch里GPU和CPU的切换,看起来只是几行代码的事——model.to(device)、torch.device(cuda:0)、DataParallel……但我在带三个团队做模型训练的四年里,亲眼见过太多人栽在这几个看似简单的环节上:刚…

2026/11/11 21:42:43

朔州怀仁电工证保姆级教程:工地太忙根本没时间复习考试?

朔州怀仁电工证保姆级教程:工地太忙根本没时间复习考试? 工地太忙根本没时间复习考试?别急,今天这波保姆级教程,专为像你这样天天在项目上跑的电工量身定制。从朔州怀仁电工证的考试内容、报名材料到证书补办流程、常见违规问题,一个不落地讲透。哪怕你…

2026/11/11 21:42:43

低压电工证是哪里发证内部消息实操考试怕挂科别慌

低压电工证是哪里发证内部消息实操考试怕挂科别慌 实操考试心里没底怕挂科?这年头连个低压电工证都得拼命考,你不是一个人。我干这行这么多年,见过太多人因为不知道低压电工证是哪里发证,被坑了报名费还白搭时间。下面我给你讲清楚,低压电工证是哪里发证…

2026/11/11 21:42:43

郑州审核电工证要几天?良心建议来了,实操考试心里没底怕挂科

郑州审核电工证要几天?良心建议来了,实操考试心里没底怕挂科 你是不是也这样?好不容易通过了理论考试,眼看就要参加实操考试了,却还是心里没底,怕挂科?这事儿,咱们都懂。特别是对于洛阳的应届毕业生,刚拿到电工证,面对郑州审核流程,一不小心就容易…

2026/11/11 21:42:43

电工证复审后怎么办?值不值得考?漯河电工从业者必看

电工证复审后怎么办?值不值得考?漯河电工从业者必看 实操考试心里没底怕挂科,这几乎是所有准备考电工证或需要复审的电工从业者的真实写照。尤其在漯河这样的市政工程活跃地区,电工证不仅是上岗的“通行证”,更是收入提升的“加速器”。但很多人复审后却…

2026/11/11 21:37:42

云浮半挂车电工证怎么考?考前押题攻略帮你避坑

云浮半挂车电工证怎么考?考前押题攻略帮你避坑 你是不是也这样, 不知道去哪报名怕被中介坑 ?在云浮,半挂车电工证的报考信息繁杂,中介多、信息真假难辨,很多人跑了几趟都没搞明白。其实,只要掌握正确的方法, 考前押题…

2026/11/11 12:42:59

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/11 20:27:01

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑