NBomber压测Kafka时RPS未达预期的问题排查及优化咨询
我正在使用NBomber对服务器上的一个Kafka实例进行负载测试,测试代码如下:
public static void Run() { var testScenario = NBomber.CSharp.Step.Create("testScenario", async context => { try { // The testData is a string variable that reads contents from a text file in the Init method. var kafkaObject = new KafkaObject { Topic = TestTopic, Message =testData }; SampleKafkaFlow sampleKafkaFlow = new SampleKafkaFlow(); var response = await sampleKafkaFlow.SendMessageToKafka(kafkaObject); return Response.Ok(); } catch (Exception ex) { return Response.Fail(ex.Message); } }); var scenario = ScenarioBuilder.CreateScenario("scenario", testScenario) .WithoutWarmUp() .WithInit(Init) .WithLoadSimulations(new[] { Simulation.InjectPerSec(rate: 100, during: TimeSpan.FromMinutes(3)) }); NBomber.CSharp.NBomberRunner .RegisterScenarios(scenario) .WithReportFileName($"testScenario-Report-{DateTime.UtcNow.ToString("yyyy-dd-M--HH-mm-ss")}") .WithReportFolder("test_reports") .WithReportFormats(ReportFormat.Html) .Run(); }
我的笔记本配置为10代酷睿i5、16GB内存,运行Windows10系统,测试时仅启动了VS2022。我原本预期以100 RPS的速率运行3分钟会产生18000次请求,但测试报告显示仅完成2057次请求。请问我忽略了什么?如何实现更高RPS的负载测试?
一、核心瓶颈点
Kafka客户端重复初始化
每次请求都新建SampleKafkaFlow实例,意味着每次请求都会重新创建Kafka生产者客户端。Kafka生产者初始化涉及TCP连接建立、配置加载等重型操作,这会极大拉长单请求耗时,直接导致RPS无法达标。资源未复用
NBomber的压测效率依赖资源复用,当前代码没有缓存Kafka生产者实例,每个请求都重复走初始化流程,单请求耗时被大幅拉高,自然无法支撑100 RPS的速率。未关注Kafka发送的实际耗时
如果SendMessageToKafka内部是同步阻塞逻辑,或者Kafka集群的ACK级别设置过高(比如all)、网络延迟大,都会导致单请求耗时过长,限制整体吞吐量。
二、具体优化步骤
复用Kafka生产者实例
在Init方法中一次性初始化SampleKafkaFlow,并存储到场景上下文,后续请求直接复用该实例:private static Task Init(IScenarioContext context) { // 仅初始化一次Kafka客户端 context.Data["KafkaFlow"] = new SampleKafkaFlow(); return Task.CompletedTask; } // Step中复用实例 async context => { try { var kafkaFlow = context.Data["KafkaFlow"] as SampleKafkaFlow; var kafkaObject = new KafkaObject { Topic = TestTopic, Message = testData }; var response = await kafkaFlow.SendMessageToKafka(kafkaObject); return Response.Ok(); } catch (Exception ex) { return Response.Fail(ex.Message); } }优化Kafka生产者配置
- 启用批量发送:设置
BatchSize(比如16384)和LingerMs(比如5),让生产者攒一批消息再发送,减少网络IO次数。 - 调整ACK级别:非强一致性需求下,将
Acks设为1(只等待主节点确认)或0(不等待确认),降低等待耗时。 - 增大缓冲区:调整
BufferMemory参数(比如67108864),避免因缓冲区满导致的发送阻塞。
- 启用批量发送:设置
调整NBomber场景配置
- 添加预热阶段:去掉
.WithoutWarmUp(),改为.WithWarmUpDuration(TimeSpan.FromSeconds(30)),让Kafka客户端建立稳定连接后再进入正式压测。 - 组合并发策略:如果单实例复用后仍无法达标,可同时使用并发用户数和速率控制,比如:
.WithLoadSimulations(new[] { Simulation.InjectConcurrent(copies: 50, during: TimeSpan.FromMinutes(3)), Simulation.InjectPerSec(rate: 100, during: TimeSpan.FromMinutes(3)) })
- 添加预热阶段:去掉
排查外部瓶颈
- 检查网络延迟:确认笔记本到Kafka服务器的网络是否存在高延迟或丢包,可通过
ping工具验证。 - 检查Kafka集群状态:查看Broker的CPU、内存、磁盘IO负载,以及是否存在消息堆积情况。
- 检查网络延迟:确认笔记本到Kafka服务器的网络是否存在高延迟或丢包,可通过
三、验证优化效果
优化后重新运行测试,重点关注NBomber报告中的Request rate、Latency percentiles指标,确认RPS是否接近预期。若仍有差距,可逐步调整并发数和Kafka配置,直到达到目标。
内容的提问来源于stack exchange,提问作者Codehelp

