ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Dapr Actor 负载压测实践:基于 actorload 的 StateActor 压测应用与 testclient 驱动详解

Dapr Actor 负载压测实践:基于 actorload 的 StateActor 压测应用与 testclient 驱动详解 Dapr Actor 负载压测实践基于 actorload 的 StateActor 压测应用与 testclient 驱动详解【免费下载链接】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/dapractorload 是 Dapr 官方仓库中用于 Actor 运行时负载压测的专用测试套件包含一个模拟业务的服务端应用stateactor被测 Actor 服务和一个基于 Fortio 的压测驱动客户端testclient负载发生器。本文将以tests/apps/actorload下的构建脚本、源码与部署清单为依据完整讲解该套件的编译、Docker 镜像构建、本地压测全流程与全部命令行参数并深入剖析其 HTTP 调用链、Actor 激活机制与结果聚合实现帮助你掌握一套可直接复用的 Dapr Actor 性能测试方案。套件构成被测服务 压测驱动tests/apps/actorload目录下的核心入口如下组成路径作用StateActor 服务tests/apps/actorload/cmd/stateactor/main.go承载StateActor类型 Actor 的 HTTP 服务作为被测对象压测客户端tests/apps/actorload/cmd/testclient/main.go按指定 QPS、并发与时长对 Actor 方法发起调用的负载发生器HTTP Actor 客户端tests/apps/actorload/pkg/actor/client/http/client.go封装 Dapr Actor HTTP APIv1.0/actors/...调用Actor 运行时配置tests/apps/actorload/pkg/actor/runtime/config.go定义 Actor 配置entities、闲置超时、排空策略遥测采集tests/apps/actorload/pkg/telemetry/telemetry.go记录每次请求的耗时、状态码等指标Kubernetes 部署清单tests/apps/actorload/deploy/面向集群压测的 Deployment / Component / Configuration从go.modtests/apps/actorload/go.mod可以看到该套件的独立模块基于 Fortiofortio.org/fortio v1.6.8驱动压测引擎、go-chichi/v5构建服务路由、OpenTelemetry Prometheus exporter 采集指标——整套工具与 Dapr 主仓库解耦可作为独立的压测模块维护。编译构建make build 与产物输出在tests/apps/actorload目录下执行make buildMakefiletests/apps/actorload/Makefile定义了构建规则BINARIES ? stateactor testclient OUT_DIR ./dist build: $(TEST_BINS) # 每个二进制由如下规则生成 $(OUT_DIR)/$(1): CGO_ENABLED0 go build -o $(OUT_DIR)/$(1) $(2)/main.go;其中通过BINARIES变量指定要生成的二进制列表默认stateactor与testclient编译时强制CGO_ENABLED0产出纯静态二进制便于放入精简容器镜像产物统一输出到./dist目录。README 中特别提示stateactor 和 testclient 会生成在./dist下。构建完成后可先查看stateactor的用法% ./dist/stateactor --help Usage of ./stateactor: -actors string Actor types array separated by comma. e.g. StateActor,SaveActor (default StateActor) -p int StateActor service app port. (default 3000)构建 Docker 镜像本地构建镜像并推送至自己的镜像仓库docker build -t [your registry]/actorload .Dockerfiletests/apps/actorload/Dockerfile采用经典的两阶段构建FROM golang:1.26.6 WORKDIR /actorload/ COPY . . RUN make build FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from0 /actorload/dist/ . CMD [./stateactor]第一阶段在golang:1.26.6中执行make build完成编译第二阶段基于alpine:latest仅复制dist目录下的两个二进制与 CA 证书镜像体积精简默认启动命令为./stateactor在集群部署中可通过 command/args 覆盖为testclient见后文 deploy 清单。本地压测全流程第一步启动 StateActor 服务dapr run --app-id stateactor --app-port 3000 -- ./dist/stateactor -p 3000--app-id stateactor为 Sidecar 指定应用 IDActor 类型全局限定名为stateactor命名空间下的StateActor--app-port 3000告知 Sidecar 应用服务监听端口./dist/stateactor -p 3000启动被测服务应用端口与 Sidecar 配置保持一致。stateactor命令行参数参数类型默认值说明-actorsstringStateActor逗号分隔的 Actor 类型数组如StateActor,SaveActor-pint3000StateActor 服务的应用端口多 Actor 类型时以逗号分隔传入例如./dist/stateactor -actors StateActor,SaveActor -p 3000。main.go 中通过strings.Split(*actors, ,)拆分后注入运行时配置的Entities字段。第二步启动压测客户端# 目标 QPS1000 qps测试 Actor 数200时长30 分钟 dapr run --app-id testclient -- ./dist/testclient -qps 1000 -numactors 200 -t 30mtestclient不暴露应用端口仅依赖 Sidecar 的 HTTP API默认127.0.0.1:3500可通过环境变量DAPR_HTTP_PORT覆盖向stateactor转发 Actor 调用。testclient命令行参数来自 tests/apps/actorload/cmd/testclient/main.go 的getFlagOptions参数类型默认值说明-astringStateActor被测 Actor 类型-cint10并行连接线程数-logcallerbooltrue日志中输出调用者文件名与行号-loglevelvalueInfo日志级别可选Debug Verbose Info Warning Error Critical Fatal-logprefixstring日志消息前缀-mstringsetActorState测试期间调用的 Actor 方法如nop、setActorState、getActorState-numactorsint10随机生成的测试 Actor 数量-qpsfloat100每线程 QPS-sint1024保存状态值的字节大小-tduration1m0s测试总时长QPS 换算-qps是每线程 QPS总吞吐 ≈-qps × -c。例如-qps 1000 -c 10理论上产生 10000 QPS 的请求压力规划压测目标时需把两者相乘计算总负载。源码级剖析StateActor 被测服务Actor 方法注册cmd/stateactor/main.go 定义了stateActor结构体并注册三个测试方法setActorState通过事务状态操作upsert写入state键调用链为SaveStateTransactionally → POST /v1.0/actors/{type}/{id}/stategetActorState读取state键调用链为GET /v1.0/actors/{type}/{id}/state/statenop空操作仅返回nop用于测量不含状态读写的纯调用开销——这也是 testclient.yml 集群压测中选择-m nop的原因。同时注册了激活/停用回调日志格式为{actorType}.{actorID}, {hostname}, Activated可用于核对各 Pod 上的 Actor 分布service.SetActivationHandler(actor.onActivated) service.SetDeactivationHandler(actor.onDeactivated) service.AddActorMethod(getActorState, actor.getActorState) service.AddActorMethod(setActorState, actor.setActorState) service.AddActorMethod(nop, actor.nopMethod)运行时配置与路由实现service/server.go 中服务通过rt.DaprConfigpkg/actor/runtime/config.go向 Sidecar 暴露 Actor 运行时参数并经由/dapr/config端点返回 JSON配置字段本应用取值含义entities-actors传入的类型该应用托管的 Actor 类型actorIdleTimeout5mActor 闲置超时超时触发停用drainOngoingCallTimeout10s停用/再平衡时等待进行中调用的排空时长drainRebalancedActorstrue是否在 Actor 再平衡时执行排空路由结构基于 go-chir.Get(/dapr/config, s.onConfig) // 向 Dapr Sidecar 提供 Actor 配置 r.Get(/healthz, s.onHealthz) // 健康检查 r.Route(/actors/{actorType}/{actorID}, func(r chi.Router) { r.Delete(/, ...) // 处理 Actor 停用 r.Put(/method/{method}, ...) // 处理方法调用 })PUT /actors/{actorType}/{actorID}/method/{method}处理逻辑源码 server.go值得注意校验method、actorType、actorID非空通过sync.Map.LoadOrStore判断该 Actor 是否首次被调用首次则触发激活处理器从invocationMap查找已注册方法未注册返回501 Not Implemented读取请求体并交给对应处理函数出错返回500成功返回方法响应体。这套首次调用即激活 方法分发的逻辑正是 Dapr Actor 运行时按需激活语义的简化复刻适合作为理解 Actor 生命周期的最小示例。HTTP Actor 客户端pkg/actor/client/http/client.go 封装了所有对 Dapr Sidecar 的 HTTP 调用地址拼接规则为http://{DAPR_HTTP_PORT 或 3500}/v1.0/actors/{actorType}/{actorID}/method/{method}接口定义pkg/actor/client/actor_client.go包含InvokeMethod、SaveStateTransactionally、GetState、WaitUntilDaprIsReady与Close五个方法。其中WaitUntilDaprIsReady会轮询GET /v1.0/healthz直到返回204才认为 Dapr 就绪——这正是压测开始前等待 Sidecar 就绪的保障。源码级剖析testclient 压测驱动测试前准备批量激活 ActorstartLoadTestcmd/testclient/main.go在正式压测前完成三件事调用WaitUntilDaprIsReady等待 Dapr Sidecar 就绪通过activateRandomActors生成-numactors个 UUID去除连字符作为 Actor ID并逐一调用setActorState写入初始值state以完成激活激活失败的 Actor 被跳过用generatePayload按-s指定大小随机生成字母数字载荷供压测期间作为请求体复用。值得注意的是激活失败率由代码统计并打印Activated actors: N若全部激活失败则直接报错终止避免测了个寂寞。Fortio 负载引擎与轮询调度压测引擎直接复用 Fortio 的periodic包r : periodic.NewPeriodicRunner(opt.RunnerOptions)每个压测线程-c持有一个独立 HTTP 客户端各自维护currentActorIndex指针按**轮询round-robin**方式遍历已激活的 Actor 列表main.goactorID : lt.actors[lt.currentActorIndex] _, err : lt.client.InvokeMethod(lt.testActorType, actorID, lt.testActorMethod, application/json, lt.payload) ... lt.currentActorIndex (lt.currentActorIndex 1) % len(lt.actors)每次调用完成后记录响应码、耗时并上报遥测同时将大小记入直方图。错误处理上DaprActorClientError会提取 HTTP 状态码如 404、500非 HTTP 错误统一记作 500最终按状态码聚合。结果聚合与输出测试结束后驱动汇总所有线程的RetCodes统计并输出各状态码占比Jitter: false Code 200 : 1000000 (100.0 %)同时输出响应体大小的直方图Response Body/Total Sizes仅在-loglevel达到 Verbose 时打印完整直方图Warning 级别以上打印计数器摘要。结合 pkg/telemetry 的 Prometheus 指标可在压测期间通过 Grafana 实时观察 QPS、延迟分布与错误率。Kubernetes 集群压测部署deploy/目录提供了面向集群的压测清单基于 Dapr 官方 e2e 压测的 loadtest 命名空间stateactor.ymlreplicas: 50annotations 声明dapr.io/enabled: true、dapr.io/app-id: stateactor、dapr.io/app-port: 3000args 为[-actors, StateActor, -p, 3000]并通过 nodeAffinity 固定调度到agentpooltestapp节点testclient.ymlreplicas: 60args 为[-a, StateActor, -c, 10, -numactors, 2048, -s, 1024, -t, 120m0s, -m, nop]即每实例 10 线程、激活 2048 个 Actor、运行 2 小时、调用nop方法nodeAffinity 固定到agentpoolloadgen节点——被测节点与压测节点物理隔离避免资源争抢污染结果redis-state.ymlstate.redis类型组件actorStateStore: true标记为 Actor 状态存储指向集群内redis-master.components.svc.cluster.local:6379notrace.yamltestappconfig配置将tracing.samplingRate设为0关闭采样以消除追踪开销对吞吐的影响压测时通过dapr.io/config: testappconfig注解引用。此外redis-override.yml用于在测试环境中覆盖 Redis 连接配置。本地压测时如需同样的去追踪效果可参考该 Configuration 关闭采样。压测方法与结果判读建议结合 README 与本套件实现推荐按以下步骤开展 Actor 压测功能冒烟以-qps 100 -c 1 -t 10s小规模运行确认stateactor日志中出现 Activate 记录、testclient 输出Code 200占比 100%分级加压固定-numactors与-s按-qps 100 → 500 → 1000逐级提升观察各状态码占比500 表示方法执行失败、非 2xx 表示 Sidecar 层错误与延迟直方图变化隔离变量nop方法测纯调度开销setActorState测状态写入路径getActorState测状态读取路径三者对比可定位瓶颈在调度还是状态存储放大 Actor 规模提高-numactors以考察大规模 Actor 激活/停用下的运行时稳定性并结合 stateactor 的激活日志核对 Actor 在 50 个副本间的分布是否均衡集群压测注意按 testclient.yml 的做法将压测源与目标节点隔离、关闭 tracingnotrace.yaml并确保 redis-state.yml 的actorStateStore已置为true。对结果的解读应关注三组数据状态码分布正确性、响应大小直方图与请求耗时延迟、遥测指标QPS 与错误率的时序曲线三者结合才能完整评估 Actor 运行时在目标负载下的表现。【免费下载链接】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),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进