主题
07 · 性能优化思路
本章只列代码中可定位的调优旋钮与已经写在配置里的默认值,不引用 cbdc-chain/docs/ 中的容量规划文档。所有具体阈值都标了出处;调优建议是"在这些旋钮的范围内可以做什么",不预设性能目标。
全栈瓶颈层
各层都有可调旋钮,下文按代码可见的顺序列出。
1. Token Selector — UTXO 选币
来源:cbdc-biz/conf/institution-001/core.yaml:35-36、cbdc-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调优旋钮
| 项 | 取值范围 | 影响 |
|---|---|---|
mode | memory / distributed | 单实例选 memory;多 Institution 实例选 distributed |
bucket_boundaries | 单调递增整数数组 | UTXO 按面值分桶;合适的分桶减少跨桶查找 |
redis.max_tokens_per_bucket | 默认 100 | 每桶最大 UTXO 数;过小限制并发选币,过大单桶争用 |
验证手段
cbdc-biz/app/institution/internal/biz/wallet_biz.go:81 中 BatchQueryBalances 有 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.yaml 的 fsc.persistences.default.opts)。
调优旋钮
- 每应用独立 DB:
dataSource中dbname=cbdc_<role>天然按角色分库,已生效。 maxOpenConns/maxIdleConns/maxIdleTime:在各角色core.yaml直接调整;上调maxOpenConns受 PostgreSQLmax_connections限制。
3. BizHub ent ORM 连接池
来源:cbdc-biz/app/bizhub/internal/data/ent_client.go:47-55。
默认(硬编码)
| 参数 | 值 |
|---|---|
MaxIdleConns | 15 |
MaxOpenConns | 50 |
ConnMaxLifetime | 30m |
ConnMaxIdleTime | 5m |
| auto-migrate | client.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调优旋钮
| 项 | 取值范围 | 影响 |
|---|---|---|
enabled | true / false | 开关索引器(背景见 cbdc-biz/app/auditor/internal/worker/INTEGRATION.md) |
batch_size | 整数 | 增大提高吞吐,但增大每次 BizHub AppendBatch 延迟 |
flush_interval | duration | 减小降低延迟、提高写入频率;增大降低 IOPS |
queue_depth | 整数 | 背压阈值;超过则上游阻塞 |
append_timeout | duration | 单次 batch 写入超时 |
retry_initial / retry_max | duration | 指数退避边界 |
shard | 字符串 | 多 Auditor 实例时用 auditor-0/-1/... 区分 cursor |
5. Auditor Worker Pool
来源:cbdc-biz/conf/auditor/core.yaml:32-34、cbdc-biz/pkg/workerpool/pool.go。
默认(实测)
yaml
audit_worker_pool:
size: 120
submit_timeout: 5s硬上限为 MaxSizeMultiplier * GOMAXPROCS,MaxSizeMultiplier = 32(pkg/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为准。
调优旋钮
| 项 | 注意 |
|---|---|
size | 受 32 * GOMAXPROCS 硬上限;超过 clamp 无效 |
submit_timeout | 0 = fail-fast;>0 = 排队 |
6. BizHub Settlement Worker 三件套
来源:cbdc-biz/app/bizhub/internal/worker/worker.go:17-68。
默认(硬编码)
| Worker | PollInterval | ConcurrentJobs | BatchSize |
|---|---|---|---|
SettlementPendingWorker | 5s | 10 | 100 |
SettlementRetryWorker | 5s | 10 | 100 |
SettlementTimeoutWorker | 30s(CheckInterval) | 0(串行,硬编码于 settlement_timeout_worker.go:38) | 50 |
MaxRetries 默认 3,ProcessingTimeout 默认 5m(cbdc-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-577、settlement_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.go、cbdc-biz/conf/bizhub/core.yaml:92-108。
配置项
| 项 | 默认 | 出处 |
|---|---|---|
smb.host / port | host.docker.internal / 445 | bizhub conf:95-96 |
smb.in_share / out_share | in / out | bizhub conf:102-103 |
smb.max_idle_conns | 5(连接池大小) | bizhub conf:106 |
smb.poll_interval | 3s(响应轮询间隔) | bizhub conf:107 |
smb.response_timeout | 30s(单请求最大等待) | bizhub conf:108 |
NewSMBPool 在 maxIdle <= 0 时回退到 5(smb_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 rulesets | auditor / institution / endorser | auditor.GetSDK() |
| Asset marks | issuer / institution / auditor | marked.GetSDK() |
| Rule groups (TxSelector) | institution / auditor | tx_selector.GetSDK() |
| Fee config | institution | StartPeriodicSync(syncFeeConfigs)(institution/cmd/institution/main.go:196;fee.InitEngine() 仅初始化引擎) |
| Revocation list | auditor | 30s 刷新(pkg/common/revocation/cache.go:32,refreshInterval = 30s) |
调优旋钮
各 SDK 同步用 syncutil.DefaultSyncInterval = 1 * time.Minute(pkg/common/syncutil/periodic.go:11);Revocation 缓存单独用固定 30s。延迟敏感场景可降低,稳定运行后可提高减负。
9. OpenTelemetry 采样率
来源:proto 字段 observability.tracing.sample_rate(double sample_rate = 2;带语义注释的为 app/auditor/internal/conf/conf.proto:73,各角色该字段行号不同:institution=71、auditor=73、endorser=35、bizhub=108、issuer=46)。各角色 core.yaml 的 observability.tracing 块只配了 endpoint,未显式设置 sample_rate,故运行时取 Go 零值 0。
调优旋钮
| 取值 | 含义 |
|---|---|
1.0 | 全量采样 |
0.1 | 10% |
0.01 | 1% |
0 | 未显式设置时的默认(auditor conf.proto:73 注释为「0=未设置(默认全量)」;SampleRatio: 0 的实际行为由外部 signet SDK 决定,本仓库无法核实) |
signet.Init 把 GetSampleRate() 映射为 OTel SDK 的 SampleRatio(pkg/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 + signet(institution/internal/server/grpc.go:17-18);bizhub 在其后追加 MTLSInstitutionMiddleware(bizhub/internal/server/grpc.go:22-26)。
调优旋钮
- 关闭非必需 middleware(如不需要 trace 时把 sample_rate=0)
- 自定义 middleware 内部避免阻塞 / 锁
- BizHub
MTLSInstitutionMiddleware(cbdc-biz/app/bizhub/internal/server/mtls_middleware.go)每请求解析客户端证书 — 高并发时可缓存 cert→institution_code 映射
11. Token Selector 16 并发
来源:cbdc-biz/app/institution/internal/biz/wallet_biz.go:81(BatchQueryBalances)。
代码硬编码 16 并发上限。若钱包数极多且并发 batch query 是瓶颈,可在源码层调整。
12. ZK 证明:gnark-crypto
来源:cbdc-biz/go.mod:70(github.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 | 默认 | 含义 |
|---|---|---|
-c | 30 | 并发 worker |
-d | 60s | 时长 |
-ramp | 2s | 慢启动 |
-mode | ring | ring / ring_once / query |
-amt | 0.50 | 单笔金额 |
-active | 0(全部) | 用前 N 个钱包 |
输出 P50 / P90 / P95 / P99 + 失败原因 top(cbdc-stress/README.md:8,222-226)。
14. pprof(生产 profile)
来源:cbdc-biz/pkg/runtime/pprof_on.go、pprof_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/Init(cbdc-biz/README.md:122) |
需要突破这些瓶颈时,要从架构层面改造(多 channel / 分片 / GPU 加速 / 多 HSM 等),不在本章覆盖范围。
验证 / 监控建议
| 监控指标 | 来源 |
|---|---|
| 各 Worker 队列深度 / 处理 latency | BizHub 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
entauto-migrate 是否有关闭开关(代码中未见,启动时无条件执行client.Schema.Create)。 - RTGS 报文往返耗时是否有内部 metric(未在
pkg/rtgs// signet 注入点确认)。