Skip to content

07 · 性能优化思路

本章只列代码中可定位的调优旋钮已经写在配置里的默认值,不引用 cbdc-chain/docs/ 中的容量规划文档。所有具体阈值都标了出处;调优建议是"在这些旋钮的范围内可以做什么",不预设性能目标。

全栈瓶颈层

各层都有可调旋钮,下文按代码可见的顺序列出。

1. Token Selector — UTXO 选币

来源:cbdc-biz/conf/institution-001/core.yaml:35-36cbdc-biz/pkg/token_selector/

默认(实测)

yaml
token_selector:
  mode: memory

注释中给出 distributed 模板(行 27-34):

yaml
# token_selector:
#   mode: distributed
#   bucket_boundaries: [100, 1000, 10000, 50000, 100000]  # defaults
#   redis:
#     addr: "host.docker.internal:6379"
#     max_tokens_per_bucket: 100  # default 100

调优旋钮

取值范围影响
modememory / distributed单实例选 memory;多 Institution 实例选 distributed
bucket_boundaries单调递增整数数组UTXO 按面值分桶;合适的分桶减少跨桶查找
redis.max_tokens_per_bucket默认 100每桶最大 UTXO 数;过小限制并发选币,过大单桶争用

验证手段

cbdc-biz/app/institution/internal/biz/wallet_biz.go:81BatchQueryBalances 有 16 并发上限——可观察该函数 latency 判断当前选币是否瓶颈。

2. FSC + Token SDK 持久化

来源:各 cbdc-biz/conf/<role>/core.yaml: fsc.persistences.default

默认

yaml
fsc:
  persistences:
    default:
      type: postgres
      opts:
        dataSource: host=... dbname=cbdc_<role> sslmode=disable  # 每应用一库
        maxOpenConns: 200
        maxIdleConns: 200
        maxIdleTime: 30s

各角色连接池上限不同(maxOpenConns / maxIdleConns):institution-001 200、auditor 160、endorser1 50、issuer 20(出处:各 conf/<role>/core.yamlfsc.persistences.default.opts)。

调优旋钮

  • 每应用独立 DB:dataSourcedbname=cbdc_<role> 天然按角色分库,已生效。
  • maxOpenConns / maxIdleConns / maxIdleTime:在各角色 core.yaml 直接调整;上调 maxOpenConns 受 PostgreSQL max_connections 限制。

3. BizHub ent ORM 连接池

来源:cbdc-biz/app/bizhub/internal/data/ent_client.go:47-55

默认(硬编码)

参数
MaxIdleConns15
MaxOpenConns50
ConnMaxLifetime30m
ConnMaxIdleTime5m
auto-migrateclient.Schema.Create(ctx)(启动时执行)

调优旋钮

建议
MaxOpenConns高并发结算请求时上调;上限受 PostgreSQL max_connections 限制
auto-migrate启动时无条件执行 client.Schema.Create,代码中无关闭开关(见 [未核])

现有索引(已优化)

来源:cbdc-biz/app/bizhub/internal/data/ent/schema/settlement_request.go:84-101

索引用途
Pending Worker 热查询(status, request_type, created_at)列顺序支持无 Sort 过滤
权限过滤(institution_id, created_at)按机构筛选
兼容旧版(request_type, status)历史保留

4. Auditor 索引器(FinalityCaptureWorker)

来源:cbdc-biz/conf/auditor/core.yaml:44-53

默认(实测)

yaml
indexer:
  enabled: true            # 该配置文件中已启用
  shard: auditor-0
  batch_size: 200
  flush_interval: 1s
  queue_depth: 10000
  append_timeout: 5s
  retry_initial: 0.1s
  retry_max: 30s
  restart_backoff: 5s

调优旋钮

取值范围影响
enabledtrue / false开关索引器(背景见 cbdc-biz/app/auditor/internal/worker/INTEGRATION.md
batch_size整数增大提高吞吐,但增大每次 BizHub AppendBatch 延迟
flush_intervalduration减小降低延迟、提高写入频率;增大降低 IOPS
queue_depth整数背压阈值;超过则上游阻塞
append_timeoutduration单次 batch 写入超时
retry_initial / retry_maxduration指数退避边界
shard字符串多 Auditor 实例时用 auditor-0/-1/... 区分 cursor

5. Auditor Worker Pool

来源:cbdc-biz/conf/auditor/core.yaml:32-34cbdc-biz/pkg/workerpool/pool.go

默认(实测)

yaml
audit_worker_pool:
  size: 120
  submit_timeout: 5s

硬上限为 MaxSizeMultiplier * GOMAXPROCSMaxSizeMultiplier = 32pkg/workerpool/pool.go:49,2026-05-08 由 16 调到 32)。size <= 0 时回退到 runtime.GOMAXPROCS(0);超过上限会被 clamp(pool.go:60-66)。submit_timeout > 0 让调用方排队,而非池满时直接 fail-fast。

注:conf/auditor/core.yaml:29 的注释仍写着旧值 16 * 8 = 128,以代码 MaxSizeMultiplier = 32 为准。

调优旋钮

注意
size32 * GOMAXPROCS 硬上限;超过 clamp 无效
submit_timeout0 = fail-fast;>0 = 排队

6. BizHub Settlement Worker 三件套

来源:cbdc-biz/app/bizhub/internal/worker/worker.go:17-68

默认(硬编码)

WorkerPollIntervalConcurrentJobsBatchSize
SettlementPendingWorker5s10100
SettlementRetryWorker5s10100
SettlementTimeoutWorker30sCheckInterval0(串行,硬编码于 settlement_timeout_worker.go:3850

MaxRetries 默认 3ProcessingTimeout 默认 5mcbdc-biz/app/bizhub/internal/biz/settlement_biz.go:34,38)。

调优旋钮

影响
PollInterval越小越实时(DB 查询频率高);越大延迟越长
ConcurrentJobs决定单 batch 内并发执行;上限受 RTGS / 链上吞吐
BatchSize单次取多少行;过大占用内存
maxRetries重试次数上限
ProcessingTimeout超时阈值;超出后 Timeout Worker 把请求改为 status=FAILED / error_code=PROCESSING_TIMEOUT / error_type=RETRYABLE(转入重试),交由 SettlementRetryWorker 处理(settlement_repo.go:571-577settlement_timeout_worker.go:47-50 仅打日志)

配置注入路径

这 3 个 Config struct 通过 NewXxxWorkerConfig() 创建(worker.go:56-68),各返回 DefaultXxxWorkerConfig() 中的硬编码默认值。如需运行时配置,需要在 Wire DI 处替换 provider(当前代码使用默认值)。

7. RTGS SMB 连接池

来源:cbdc-biz/pkg/rtgs/smb_pool.gocbdc-biz/conf/bizhub/core.yaml:92-108

配置项

默认出处
smb.host / porthost.docker.internal / 445bizhub conf:95-96
smb.in_share / out_sharein / outbizhub conf:102-103
smb.max_idle_conns5(连接池大小)bizhub conf:106
smb.poll_interval3s(响应轮询间隔)bizhub conf:107
smb.response_timeout30s(单请求最大等待)bizhub conf:108

NewSMBPoolmaxIdle <= 0 时回退到 5smb_pool.go:22-23)。

调优旋钮

调高 max_idle_conns 可提升 RTGS 报文并发;不调高则 settlement Worker 即使提高 ConcurrentJobs,也会被 SMB 串行化。

8. 配置缓存刷新(syncutil)

来源:cbdc-biz/pkg/common/syncutil/;各 SDK 在 pkg/common/<sdk>/sdk.go 内部经 syncutil.StartPeriodicSync 启动周期同步,Fee config 则由 app/institution/cmd/institution/main.go:196 单独触发。

缓存项应用同步触发
Auditor rulesetsauditor / institution / endorserauditor.GetSDK()
Asset marksissuer / institution / auditormarked.GetSDK()
Rule groups (TxSelector)institution / auditortx_selector.GetSDK()
Fee configinstitutionStartPeriodicSync(syncFeeConfigs)institution/cmd/institution/main.go:196fee.InitEngine() 仅初始化引擎)
Revocation listauditor30s 刷新(pkg/common/revocation/cache.go:32refreshInterval = 30s

调优旋钮

各 SDK 同步用 syncutil.DefaultSyncInterval = 1 * time.Minutepkg/common/syncutil/periodic.go:11);Revocation 缓存单独用固定 30s。延迟敏感场景可降低,稳定运行后可提高减负。

9. OpenTelemetry 采样率

来源:proto 字段 observability.tracing.sample_ratedouble sample_rate = 2;带语义注释的为 app/auditor/internal/conf/conf.proto:73,各角色该字段行号不同:institution=71、auditor=73、endorser=35、bizhub=108、issuer=46)。各角色 core.yamlobservability.tracing 块只配了 endpoint,未显式设置 sample_rate,故运行时取 Go 零值 0

调优旋钮

取值含义
1.0全量采样
0.110%
0.011%
0未显式设置时的默认(auditor conf.proto:73 注释为「0=未设置(默认全量)」;SampleRatio: 0 的实际行为由外部 signet SDK 决定,本仓库无法核实)

signet.InitGetSampleRate() 映射为 OTel SDK 的 SampleRatiopkg/signet/signet.go:41,74)。

10. gRPC 中间件链

来源:各 app internal/server/grpc.go

recovery → signet.Middlewares() (tracing → metrics) → 自定义中间件

signet.Middlewares()pkg/signet/signet.go:100)是统一接入点。institution 只装 recovery + signetinstitution/internal/server/grpc.go:17-18);bizhub 在其后追加 MTLSInstitutionMiddlewarebizhub/internal/server/grpc.go:22-26)。

调优旋钮

  • 关闭非必需 middleware(如不需要 trace 时把 sample_rate=0)
  • 自定义 middleware 内部避免阻塞 / 锁
  • BizHub MTLSInstitutionMiddlewarecbdc-biz/app/bizhub/internal/server/mtls_middleware.go)每请求解析客户端证书 — 高并发时可缓存 cert→institution_code 映射

11. Token Selector 16 并发

来源:cbdc-biz/app/institution/internal/biz/wallet_biz.go:81BatchQueryBalances)。

代码硬编码 16 并发上限。若钱包数极多且并发 batch query 是瓶颈,可在源码层调整。

12. ZK 证明:gnark-crypto

来源:cbdc-biz/go.mod:70github.com/consensys/gnark-crypto v0.20.1,间接依赖;pkg/workerpool/pool.go:33 注释提到 gnark-crypto ZK validate 是池内 CPU 工作)。

ZK 证明生成 / 验证是 zkatdlog driver 的计算热点(fabric-token-sdk · zkatdlog)。代码层旋钮基本由 SDK 决定;调优空间在:

  • 单笔证明大小由驱动决定
  • 批量验证 / 并行验证 — 由 audit_worker_pool.size 控制

13. cbdc-stress 验证

来源:cbdc-stress/main.go:26-35

性能验证用同仓库的纯 Go 压测工具:

sh
go run . -url http://<inst>:9502 -c 30 -d 60s -ramp 2s -mode ring -amt 0.50
flag默认含义
-c30并发 worker
-d60s时长
-ramp2s慢启动
-moderingring / ring_once / query
-amt0.50单笔金额
-active0(全部)用前 N 个钱包

输出 P50 / P90 / P95 / P99 + 失败原因 top(cbdc-stress/README.md:8,222-226)。

14. pprof(生产 profile)

来源:cbdc-biz/pkg/runtime/pprof_on.gopprof_off.go,各 app cmd/<role>/main.go 中调用 pruntime.StartPprof

StartPprof 默认是 no-op(pprof_off.go//go:build !pprof);仅在带 pprof build tag 时编入实现(pprof_on.go//go:build pprof):

sh
go build -tags pprof ...

启用后在 localhost:6060 暴露 /debug/pprof/*pprof_on.go:51-53),可用 go tool pprof 分析 CPU / heap / goroutine / block。

[代码层无法调整的瓶颈]

以下设计上由协议或算法决定,单纯调配置无法显著改善:

原因
Arma BFT 共识吞吐协议层(fabric-x-orderer),与节点 / shard 数相关
Committer Coordinator 单活跃fabric-x-committer 设计,多 Coordinator 不能并列
ZK 证明单笔生成时间gnark-crypto 的椭圆曲线运算常数
HSM 单设备签名 QPS物理 HSM 设备上限
Endorser 令牌参数初始化本地需手动 grpcurl -plaintext localhost:9300 cbdc_biz.v1.EndorserService/Initcbdc-biz/README.md:122

需要突破这些瓶颈时,要从架构层面改造(多 channel / 分片 / GPU 加速 / 多 HSM 等),不在本章覆盖范围。

验证 / 监控建议

监控指标来源
各 Worker 队列深度 / 处理 latencyBizHub pkg/signet OTel 注入;可拉到 Prometheus
ent ORM 连接占用database/sql 默认 db.Stats()
Settlement 失败原因分布settlement_request.error_code / error_type
Auditor 索引 cursor 滞后index_cursor 表 vs 链上最新块号
RTGS 报文往返耗时bizhub pkg/rtgs/(是否有内部 metric 见 [未核])

[未核]

  • BizHub ent auto-migrate 是否有关闭开关(代码中未见,启动时无条件执行 client.Schema.Create)。
  • RTGS 报文往返耗时是否有内部 metric(未在 pkg/rtgs/ / signet 注入点确认)。