news 2026/9/12 22:52:29

Dapr Workflows 性能测试指南:基于 k6 与 K8s 的并发压测方案全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Dapr Workflows 性能测试指南:基于 k6 与 K8s 的并发压测方案全解析

Dapr Workflows 性能测试指南:基于 k6 与 K8s 的并发压测方案全解析

【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/dapr

导读

本文围绕 Dapr 仓库中的 tests/perf/workflows/README.md 展开,完整讲解 Dapr Workflows 性能测试套件的设计思路与运行机制。测试由 Go 测试框架驱动、k6 施加负载,覆盖恒定虚拟用户数、恒定迭代数、最大并发、延迟工作流与不同负载大小等常见模式。读完本文,你将掌握每个测试场景的 VU/迭代组合、sum_series_wf/sum_parallel_wf/state_wf/delay_wf等被测工作流的构造方式、App 与 Sidecar 资源监控的采集方法,以及如何利用tests/perf/report将 k6 JSON 报告渲染成可视化图表。

测试目标与整体架构

该测试套件的目标是:在 Kubernetes 集群上部署perf-workflowsapp应用及其 Dapr Sidecar,通过 k6 向工作流应用发送 HTTP 请求,评估 Dapr Workflows 在常见负载模式下的性能表现。测试结果不仅包含 k6 自身的延迟与吞吐指标,还同步采集 App 与 Sidecar 的 CPU/内存使用量及重启次数,最终汇总成一张摘要表,并输出图表到 tests/perf/report/charts/v1.16.3/workflows/。

整个套件由三部分协作完成:

  1. Go 测试驱动:workflow_test.go 负责部署应用、准备 k6 环境、执行压测并采集资源数据;
  2. k6 脚本:test.js 定义各类压测场景(VU 数、迭代数、执行器与超时时间);
  3. 报告渲染:tests/perf/report 下的charts.go将 gotestsum 的 JSON 报告转换为 PNG 图表。

术语表(Glossary)

术语含义
VU(Virtual User)同一时刻并发运行的工作流数量
Iterations工作流运行的总次数
Req_Duration完成一次工作流运行所花费的时间
SidecarDapr Sidecar 进程

测试计划:部署与公共流程

部署拓扑

所有测试共享同一套部署拓扑:在 Kubernetes 集群上部署单实例的perf-workflowsapp(镜像名为perf-workflowsapp,应用端口与 Ingress 端口均为 3000),并启用 Dapr Sidecar。资源请求/限制通过AppDescription结构体中的App*Dapr*字段配置,具体数值定义在 workflow_test.go 的TestMain中:

字段
DaprCPULimit1.0
DaprCPURequest0.5
DaprMemoryLimit2Gi
DaprMemoryRequest1Gi
AppCPULimit2.0
AppCPURequest1.0
AppMemoryLimit2Gi
AppMemoryRequest1Gi
Replicas1

此外,测试还定义了一个scaledAppNameperf-workflowsapp-scaled),以scaledReplicas = 3副本部署,用于多实例场景下验证工作流与活动跨实例分布的表现。

所有场景的公共流程

  • 使用 k6 向工作流应用发送 HTTP 请求;
  • 在开始加压之前初始化工作流运行时;
  • 收集 k6 指标,以及 App/Sidecar 的资源使用量与重启次数,写入摘要表;
  • 测试结束后将指标汇总至 tests/perf/report/charts/v1.16.3/workflows/ 下的图表。

每次子测试的核心执行流程封装在testWorkflow()函数中(workflow_test.go):

  1. restart为 true,先通过tr.Platform.Restart(testAppName)重启应用以清空上一次运行的内存与状态;
  2. 获取应用的外部 Ingress URL;
  3. 调用utils.HealthCheckApps(externalURL)确认应用健康;
  4. 调用http://<externalURL>/start-workflow-runtime初始化工作流运行时(对多副本应用循环调用scaledReplicas * 3次,确保所有实例都已初始化),随后 sleep 5 秒;
  5. 构造 k6 运行配置K6RunConfig(目标 URL、场景名、工作流名、工作流输入、通过率检查表达式),调用runk6test()执行压测;
  6. 对于负载大小测试(payloadTest为 true),额外将输入字节数换算为 KB 输出到摘要表;
  7. 通过addTestResults()采集资源数据(见下文)并写入摘要表,最后table.Flush()落盘。

资源与指标采集

addTestResults()(workflow_test.go)通过tr.Platform提供的三个方法采集:

  • GetAppUsage(testAppName):应用 Pod 的内存(MB)与 CPU(m)使用量;
  • GetSidecarUsage(testAppName):Sidecar 的内存与 CPU 使用量;
  • GetTotalRestarts(testAppName):应用重启总次数。

同时将 k6 汇总指标写入摘要表,包括:VUs Max、Iterations Count、HTTP 请求时长(Req Duration,ms)、HTTP 请求等待时长(Req Waiting,ms)与迭代时长(Iteration Duration,ms)。

k6 场景定义详解

test.js 定义了完整的场景库。每个场景使用shared-iterations执行器,即固定 VU 数共享固定总量的迭代,所有迭代完成后场景结束:

场景名VUsIterationsmaxDuration
t_30_30030300200s
t_60_30060300380s
t_90_30090300380s
t_350_140035014001000s
t_110_440110440450s
t_80_80080800420s
t_500_10000500100003600s

场景名遵循t_<workflowCount>_<iterations>的命名约定。运行时会通过__ENV.SCENARIO环境变量选择唯一启用的场景(enabledScenarios[__ENV.SCENARIO])。

脚本通过 k6 环境变量接收配置:

  • TARGET_URL:工作流运行接口地址(http://<app>/run-workflow);
  • SCENARIO:场景名,如t_30_300
  • WORKFLOW_NAME:要运行的工作流名;
  • WORKFLOW_INPUT:工作流输入(数字或负载大小);
  • RATE_CHECK:通过率阈值表达式,如rate==1,作为 k6 的checksthreshold 生效。

压测主流程execute()workflow_nameworkflow_input封装为 JSON,向${TARGET_URL}/${iterationInTest}发起 HTTP POST 请求,并以响应状态码 2xx 作为通过检查(check)。teardown()阶段会调用 Dapr Sidecar 的http://127.0.0.1:${DAPR_HTTP_PORT}/v1.0/shutdown接口触发优雅关闭。

五大测试场景逐一解析

测试函数均通过//go:build perf构建标签隔离,仅在-tags=perf下编译,并使用testWorkflow()通用执行器驱动。各测试传入rateChecks矩阵(如rate==1)作为每次运行的 k6 通过率要求。

TestWorkflowWithConstantVUs:恒定 VU 数

被测工作流sum_series_wf,包含 5 个链式(串行)活动,每个活动执行数值计算并把结果返回给工作流。

场景设计

  • 输入:["100"]
  • 场景:["t_30_300", "t_30_300", "t_30_300"](30 VU、300 总迭代)
  • 同一场景连续运行 3 次,不重启应用(restart=false),用于观察多次连续运行下延迟与资源使用的稳定性(workflow_test.go)。

每次运行结束后记录 k6 延迟与吞吐指标、App/Sidecar 的 CPU/内存使用量,以及总重启次数。

TestWorkflowWithConstantIterations:恒定迭代数、递增 VU

被测工作流:同样是sum_series_wf(5 个链式数值计算活动)。

场景设计

  • 输入:["100"]
  • 场景:["t_30_300", "t_60_300", "t_90_300"](总迭代恒定为 300,VU 从 30 递增到 90)
  • 每次子测试运行前重启应用以清空状态restart=true),从而隔离"在相同总工作量下,增大 VU 数对延迟与资源使用的影响"(workflow_test.go)。

TestSeriesWorkflowWithMaxVUs:串行工作流高并发压测

被测工作流sum_series_wf,5 个链式活动,以更高的 VU 数对串行工作流施压。

场景设计

  • 输入:["100"]
  • 场景:["t_350_1400"](350 VU、1400 迭代)
  • 校验所有工作流实例均成功完成,并记录 App/Sidecar 资源使用量与延迟指标(workflow_test.go)。

TestParallelWorkflowWithMaxVUs:并行工作流高并发压测

被测工作流sum_parallel_wf,包含 5 个并行执行的活动,其结果由工作流聚合——即经典的扇出/扇入(fan-out/fan-in)模式。

场景设计

  • 输入:["100"]
  • 场景:["t_110_440"](110 VU、440 迭代)
  • 重点考察负载下扇出/扇入行为的性能表现,同样记录 k6 指标与资源使用量(workflow_test.go)。

TestWorkflowWithDifferentPayloads:不同负载大小

被测工作流state_wf,执行状态操作,内部由 3 个活动组成:

  • 活动 1:将指定大小的数据保存到配置的状态存储(state store);
  • 活动 2:读回已保存的数据;
  • 活动 3:删除该数据。

工作流以数据大小作为输入,并将该大小的字符串作为负载传给活动。

场景设计

  • 场景恒定为["t_30_300"],负载大小取["10000", "50000", "100000"]字节;
  • 对每种负载大小:运行相同的 k6 场景,记录延迟、吞吐与 App/Sidecar 资源使用,将有效负载大小输出到摘要表,并在每次运行之间重启应用(workflow_test.go)。

多实例与延迟工作流补充场景

除 README 列出的五大场景外,workflow_test.go 还实现了三个扩展场景,与上述测试共用同一套testWorkflow()执行框架:

TestSeriesWorkflowMultiInstance / TestParallelWorkflowMultiInstance

针对 3 副本的scaledAppName部署运行sum_series_wft_30_300)与sum_parallel_wft_110_440),验证工作流与并行活动的扇出/扇入跨多个 Dapr 实例分布时的表现(workflow_test.go)。

TestDelayWorkflowsAtScale

延迟工作流压测:运行delay_wf,输入"5000"表示延迟毫秒数(5 秒),场景为t_500_10000(500 VU、10000 迭代,maxDuration 3600s),考察大量工作流同时处于"等待/延时"状态时的运行时稳定性(workflow_test.go)。这也是t_500_10000场景在 test.js 中单独存在的用途。

如何运行 Workflows 性能测试

性能测试的构建与运行入口集中在 tests/dapr_tests.mk:

  • PERF_TEST_APPS中包含workflowsapp,即性能测试应用清单(tests/dapr_tests.mk);
  • PERF_TESTS中包含workflows(tests/dapr_tests.mk);
  • Makefile 通过genPerfTestRun模板为每个性能测试生成test-perf-<name>目标(tests/dapr_tests.mk),运行方式为:
make test-perf-workflows

该目标要求先满足check-e2e-envtest-deps前置条件,内部使用gotestsum-tags=perf ./tests/perf/workflows/...编译执行,并生成 JSON/JUnit 格式的测试输出(--jsonfile--junitfile),超时上限为 2 小时、-count=1禁用测试缓存。整体链路perf-build-deploy-run则串联init-build-deploy → setup-test-components → build-perf-app-all → push-perf-app-all → test-perf-all(tests/dapr_tests.mk)。

执行环境依赖DAPR_TEST_NAMESPACEDAPR_TEST_TAGDAPR_TEST_REGISTRY等环境变量指定目标集群与镜像仓库;若要单独挑选某个性能测试,可设置DAPR_PERF_TEST环境变量(tests/dapr_tests.mk)。

结果可视化:从 JSON 报告到图表

图表分类与平均规则

性能测试会重复运行同一场景(如TestWorkflowWithConstantVUs/[T_30_300]:_运行 3 次),tests/perf/report 下的charts.go会:

  • 归一化子测试名,剥离:_/:_#NN后缀,使同一逻辑测试的所有运行共享同一 key(如TestWorkflowWithConstantVUs_T_30_300);
  • 若同一逻辑测试有多次运行,则按指标逐项求平均,生成带_avg后缀的平均图表,并额外生成*_duration_comparison.png比较各次运行的延迟差异;
  • 若只有一次运行,则直接生成不带_avg的图表。

图表类型

针对每个测试,会生成以下图表(示例见 tests/perf/report/charts/v1.16.3/workflows/):

  1. 时长分解图(*_avg_duration_breakdown.png/*_avg_duration_low.png:X 轴为百分位min/med/avg/p90/p95/max,Y 轴为秒;折线来自 k6 指标http_req_connectinghttp_req_tls_handshakinghttp_req_sendinghttp_req_receivinghttp_req_blockedhttp_req_waitinghttp_req_durationiteration_durationhttp_req_failed。全范围图展示整体(含延迟工作流的长时间http_req_waiting),低延迟图则动态缩放到 0~N 秒窗口以观察短耗时阶段。
  2. 性能摘要图(*_avg_summary.png:柱状展示成功率(checks.rate * 100)、失败率与 VUs(vus_max.values.max),回答"该场景是否通过、驱动测试需要多少虚拟用户"。
  3. 吞吐图(*_avg_throughput.png:迭代/秒作为标题,柱状展示接收数据速率(data_received.values.rate / 1024,KB/s)与发送数据速率(data_sent.values.rate / 1024,KB/s)。
  4. 数据量图(*_avg_data_volume.png:按总量自动选择单位(<1MB 用 KB、≥1GB 用 GB、否则用 MB),柱状展示整个测试生命周期的收发总字节数,便于对比不同负载大小或不同时长的场景。
  5. 运行间时长对比图(*_duration_comparison.png:X 轴为 Run 1/2/3…,Y 轴为延迟(ms),折线为每次运行的 p50(中位数)与 p95(尾延迟),用于判断运行稳定性:折线平坦说明性能一致,出现尖峰或趋势则说明运行间存在波动。

本地生成图表

charts.go读取 gotestsum JSON 报告(支持直接读取.gz压缩包)并输出 PNG 到charts/<version>/<api>/

cd tests/perf/report go run . -input data/v1.18.0/test_report_perf.json.gz -version v1.18.0

常用参数:-input(报告路径,默认./test_report_perf.json)、-versioncharts/下的输出子目录,默认master)、-infra(运行基础设施描述,CI 传入 tests/test-infra/perf-infra-description.txt 以保证结果可比)、-manifest(额外输出 docs 站点使用的 manifest JSON)。设置CHARTS_DEBUG=1可查看测试分类的详细输出。每个 API 的 README 顶部还会生成"Throughput per resource"表:各场景的迭代/秒、App 与 Sidecar 的 CPU/内存消耗,以及每 CPU 核心、每 GB 内存的迭代数(app + sidecar 合并),这是跨场景、跨版本比较效率的核心指标。

结果归档与版本管理策略

按 tests/perf/report/charts/README.md 的说明,性能结果的事实来源(source of truth)是 CI 运行产生的 gotestsum JSON 报告,而非渲染后的 PNG:

  • 每个版本的压缩报告提交在tests/perf/report/data/<version>/test_report_perf.json.gz
  • 渲染图表作为perf-charts-<version>.zip发布到对应版本,同时将图表与manifest.json推送到perf-charts分支的<minor>/目录(如v1.18/);
  • 默认分支不提交新版本的完整图表集(每个版本数 MB 且 PNG 无法事后重新生成),因为 JSON 报告可以随时用当前图表代码重新渲染。

小结

Dapr Workflows 性能测试套件是一套完整、可复现的压测方案:以 Go 测试编排生命周期、以 k6shared-iterations场景控制并发模型、以摘要表与图表沉淀结果。通过本指南,你可以按需扩展possibleScenarios或新增测试函数,复现并对比不同版本、不同基础设施下 Dapr Workflows 的串行链、并行扇出/扇入、状态读写与延迟场景的性能表现。若需深入底层实现,可继续阅读 pkg/runtime/wfengine 下 Dapr Workflows 引擎源码,以及 tests/e2e/workflows/workflow_test.go 中对应的端到端功能验证。

【免费下载链接】daprDapr is a portable runtime for building distributed applications across cloud and edge, combining event-driven architecture with workflow orchestration.项目地址: https://gitcode.com/GitHub_Trending/da/dapr

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 22:47:50

即梦AI替代方案:4款国产AIGC工具实测与工作流重构指南

1. 这不是“替代”&#xff0c;是重新定义工作流&#xff1a;为什么我们需要即梦AI的务实替代方案最近两周&#xff0c;我收到不下17条私信&#xff0c;清一色问&#xff1a;“即梦AI用不了了&#xff0c;有没有真正能接住手头活儿的替代工具&#xff1f;”——注意&#xff0c…

作者头像 李华
网站建设 2026/9/12 22:47:03

基于Android Studio的校园外卖App实战:订单状态机与定位轨迹全解析

简介&#xff1a;这是一套基于Android Studio开发的校园外卖App项目源码&#xff0c;面向Android学习者、毕业设计开发者等需要完整移动端后台管理场景的人群。项目以校园场景为切入点&#xff0c;覆盖用户端从注册登录、商家模糊搜索、菜单查看、加购下单到订单评价的完整流程…

作者头像 李华
网站建设 2026/9/12 22:45:45

SpringBoot+MyBatis开发老龄化社区服务平台实战教程

简介&#xff1a;基于Java与SpringBoot构建的人口老龄化社区服务与管理平台&#xff0c;是一套面向高校计算机专业毕业设计及课程设计的完整项目源码包。系统按管理员、员工、用户三类角色设计&#xff0c;用户端支持注册登录、修改密码、查看社区信息与文件、浏览活动并报名、…

作者头像 李华
网站建设 2026/9/12 22:42:35

无人机航电系统技术演进与DHCAA架构解析

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

作者头像 李华