diff --git a/.idea/misc.xml b/.idea/misc.xml index 87a20fc..fc1f2cb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/account/alice.pem b/account/alice.pem index 10ef470..f5bc7c9 100644 --- a/account/alice.pem +++ b/account/alice.pem @@ -1,11 +1,11 @@ -----BEGIN PRIVATE KEY----- -1120cf8793ccb6df2a4a4f371503e9699d1512d2e35d73daa3202c20c8e11731 +92cbe1d3631be230ee9541ee877985a90ad2b501b089e2f0a5a6f1b99580aaec -----END PRIVATE KEY----- -----BEGIN PUBLIC KEY----- -6b68d579030462d7a0232b65a96c19a27bc98fd12ba8e5b09fdc83237ee54191ce8ff77d630341209d26bcd04640cf9e95f96af08718da3d258cef5e6e99bd08 +c13154e64419e5febe4c749d2070dea70aa83519ceac2a39da4efbcd9a9485121b202ffa9cc6a7822c046ec959d0a8ba738a5f0010f8863523ed6a386a837be9 -----END PUBLIC KEY----- -----BEGIN ADDRESS----- -0xfffecbb1ef05e897e8d7f9da10fa13255c5c7b17 +0x1664cc33e0c6e2c7573b9c2ff8438862ecd8dce8 -----END ADDRESS----- -----BEGIN CRYPTO TYPE----- 1 diff --git a/account/bob.pem b/account/bob.pem index 18e0066..c12d191 100644 --- a/account/bob.pem +++ b/account/bob.pem @@ -1,11 +1,11 @@ -----BEGIN PRIVATE KEY----- -23230366ba1af4d9fe798a4891302e6f4d765f2cdb4e47836ceac4a3d5f50967 +391db7ce3e7f627656f44db9ec8bd3f2b8626537f90d464d6a87298abac18b32 -----END PRIVATE KEY----- -----BEGIN PUBLIC KEY----- -8bd59280cc6deee3de64d88c45227cf1342a6603607e30099371a0b5ab469e832dc2b72a00f7c3acbc5b40fc6a0fc298ae8545467e67dab4d3037b129c608ba9 +46c2de937ba38b9aa93efa9685ea846b54c0c38dda02725a9ecc46c3dbd8f9ccec849fa3f0c656031e5e3c6c572216f9864e591f1b94e7288451337e1cdb04bc -----END PUBLIC KEY----- -----BEGIN ADDRESS----- -0x863a9a841c4242c7cab7ab3d5399f41ae21d05f9 +0xcfb8fd63efa74f85ae85cc8b1b90b6cab37527d2 -----END ADDRESS----- -----BEGIN CRYPTO TYPE----- 1 diff --git a/account/charlie.pem b/account/charlie.pem index 4c5f19f..be8fd75 100644 --- a/account/charlie.pem +++ b/account/charlie.pem @@ -1,11 +1,11 @@ -----BEGIN PRIVATE KEY----- -3855d3f52955a2ff799d52996fa0828d077d8dbb19242e6bd1d7b3a6f8dfbf29 +3a84aba1875141cc011b2202f802fa8f7929dd371c00909af78ef267bbff29da -----END PRIVATE KEY----- -----BEGIN PUBLIC KEY----- -aeb5629ca59d24e78f0aab53a03405fc6814316a1bdac4fba56385e8639b10d8ab04a53a7b7d94a5138f51ee02de7a7481ff8dc350c1b5d015dfa95273f48025 +72141f6b0d2147a91d994109b01885995b32f31d1c1b2b1ef3dcc6ec86f92e462568ad0c5f1bfb02afbb01bc682b15eb85dc2af7b61443e3feee23005ade12fd -----END PUBLIC KEY----- -----BEGIN ADDRESS----- -0xdb52dabfe568e15331d302f4d9a411d6993c3606 +0x8931c1ede9b32a0e8d740707008a156af2adf985 -----END ADDRESS----- -----BEGIN CRYPTO TYPE----- 1 diff --git a/account/user_pem.pem b/account/user_pem.pem index 4b100c1..c9a7eb3 100644 --- a/account/user_pem.pem +++ b/account/user_pem.pem @@ -1,11 +1,11 @@ -----BEGIN PRIVATE KEY----- -e9c890670f4af89b804ea94e4068f604170d6c39f428bc04b62e8e2b5d05fdf2 +19b62893e08eee9432c5a1f9703722634c6f12cf6ef84d49038eb672e0a72a1f -----END PRIVATE KEY----- -----BEGIN PUBLIC KEY----- -f7e50297ef82600b324685265cae5b3e9030fd3c8d45b643a1c4316ecfae282b1a241c3f1d42d1d129a24d66f636dcb17b3e0a4ca34b3cb6475f774e1cb0b83a +229e8d0b4d5519540fce3a030947a4e80ace4a8cfc73cc751abc82acf5e31f4a666bc7a9c8a3f64877be59b176e1cd1b5caf0fcc4e258cba8b122c2a1573faee -----END PUBLIC KEY----- -----BEGIN ADDRESS----- -0x7843803067240dd872e50a26b254c83bc77d77ed +0x90e1523ceb879f91c04dcf40453b82276ceb680a -----END ADDRESS----- -----BEGIN CRYPTO TYPE----- 1 diff --git a/build.gradle b/build.gradle index fbe068a..7f27572 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,12 @@ plugins { group = 'org.example' version = '1.0-SNAPSHOT' +// 设置 Java 版本兼容性 +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + repositories { mavenCentral() } @@ -27,5 +33,39 @@ test { } application { - mainClass = 'com.org.fisco.AccountGenerator' -} \ No newline at end of file + mainClass = 'com.org.fisco.TPSTest' +} + +// 创建 Fat JAR(包含所有依赖的可执行jar) +tasks.register('fatJar', Jar) { + archiveClassifier = 'all' + archiveFileName = 'tps-test.jar' + + manifest { + attributes( + 'Main-Class': 'com.org.fisco.TPSTest', + 'Implementation-Title': 'FISCO BCOS TPS Test Tool', + 'Implementation-Version': version + ) + } + + // 包含编译后的类 + from sourceSets.main.output + + // 包含所有运行时依赖 + from { + configurations.runtimeClasspath.collect { + it.isDirectory() ? it : zipTree(it) + } + } + + // 排除签名文件 + exclude 'META-INF/*.SF' + exclude 'META-INF/*.DSA' + exclude 'META-INF/*.RSA' + + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + +// 让 build 任务依赖 fatJar +build.dependsOn fatJar \ No newline at end of file diff --git a/doc/FISCO_BCOS_TPS测试指南.md b/doc/FISCO_BCOS_TPS测试指南.md new file mode 100644 index 0000000..3df4791 --- /dev/null +++ b/doc/FISCO_BCOS_TPS测试指南.md @@ -0,0 +1,607 @@ +# FISCO BCOS TPS压力测试指南 + +> **文档版本**: v2.0 +> **更新日期**: 2026-02-10 +> **适用版本**: FISCO BCOS 2.x / 3.x + +--- + +## 📋 目录 + +1. [测试工具介绍](#测试工具介绍) +2. [快速开始](#快速开始) +3. [测试参数配置](#测试参数配置) +4. [运行测试](#运行测试) +5. [结果分析](#结果分析) +6. [常见问题排查](#常见问题排查) +7. [性能优化建议](#性能优化建议) + +--- + +## 测试工具介绍 + +### 🎯 TPSTest.java + +本项目提供的 `TPSTest.java` 是一个完整的TPS压测工具,具有以下特性: + +**核心功能:** +- ✅ 自动连接FISCO BCOS节点 +- ✅ 使用 ParallelTransfer 合约进行并行转账测试 +- ✅ 支持多线程并发压测 +- ✅ 实时监控TPS、成功率 +- ✅ 自动生成详细测试报告 +- ✅ 支持QPS限流控制 + +**测试原理:** +``` +多线程并发 → 发送转账交易 → 统计响应时间 → 计算TPS和延迟 +``` + +**文件位置:** +``` +src/main/java/com/org/fisco/TPSTest.java +``` + +--- + +## 快速开始 + +### 前提条件 + +1. **合约已部署** + - 合约地址:在代码第284行设置 + - 默认使用:`0x06ac2fe406f1ae06494946ee281d58f1c79c39e4` + +2. **账户已初始化** + - 使用 `fisco/console/init_accounts.sh` 脚本初始化账户余额 + - 或手动在控制台初始化至少100个账户 + +3. **SDK配置正确** + - 配置文件:`src/main/resources/config.toml` + - 确保能连接到你的链节点 + +### 5分钟快速测试 + +```bash +cd /Users/kiro/IdeaProjects/contract + +# 1. 编译项目 +./gradlew build + +# 2. 直接运行测试 +./gradlew run +``` + +测试会自动: +1. 连接到链节点 +2. 初始化合约对象 +3. 生成测试账户 +4. 开始压测 +5. 输出测试报告 + +--- + +## 测试参数配置 + +### 🔧 核心参数说明 + +在 `TPSTest.java` 的 `main` 方法中(第277-281行)配置: + +```java +tester.setTestParams( + threadCount, // 并发线程数 + totalTransactions, // 总交易数 + qpsLimit // QPS限制(0表示不限制) +); +``` + +### 参数详解 + +#### 1. 并发线程数 (threadCount) + +**作用:** 控制同时发送交易的线程数量 + +**推荐值:** +| 测试场景 | 推荐值 | 说明 | +|---------|--------|------| +| 基准测试 | 1 | 测试单笔交易延迟 | +| 初步压测 | 50-100 | 找到基本TPS水平 | +| 寻找峰值 | 100-200 | 逐步增加找峰值 | +| 极限压测 | 200-500 | 测试系统极限 | + +**⚠️ 注意:** +- 并发数过高会导致成功率下降 +- 并发数过低无法达到TPS峰值 +- **建议从小到大逐步测试** + +#### 2. 总交易数 (totalTransactions) + +**作用:** 本次测试发送的交易总数 + +**推荐值:** +| 测试类型 | 推荐值 | 测试时长(估算) | +|---------|--------|----------------| +| 快速验证 | 1,000 | 1-5秒 | +| 基础测试 | 10,000 | 10-30秒 | +| 标准测试 | 50,000 | 1-2分钟 | +| 长期测试 | 100,000+ | 5分钟以上 | + +**原则:** +- ✅ 测试时长至少30秒以上才准确 +- ✅ 交易数太少会受启动开销影响 +- ✅ 交易数太多会耗时过长 + +#### 3. QPS限制 (qpsLimit) + +**作用:** 限制每秒发送的交易数 + +**设置建议:** +- `0`:不限制,全力压测(推荐) +- `5000`:温和测试,适合生产环境验证 +- `10000+`:根据节点能力设置上限 + +--- + +## 运行测试 + +### 方法1:使用默认参数运行 + +```bash +cd /Users/kiro/IdeaProjects/contract +./gradlew run +``` + +### 方法2:修改参数后运行 + +编辑 `src/main/java/com/org/fisco/TPSTest.java`: + +```java +// 第277-281行 +tester.setTestParams( + 100, // 改为你想要的并发数 + 10000, // 改为你想要的交易总数 + 0 // 0表示不限速 +); +``` + +然后运行: +```bash +./gradlew build && ./gradlew run +``` + +### 观察实时输出 + +测试运行时会显示: + +``` +======================================== + FISCO BCOS TPS压力测试工具 +======================================== + +连接FISCO BCOS节点成功 +当前区块高度: 12345 +使用已部署的合约地址: 0x06ac... +合约对象初始化完成 + +生成测试账户列表... +已生成 100 个测试账户 +账户列表生成完成,账户余额已通过 init_accounts.sh 脚本初始化 + +[3/3] 开始压力测试... +测试配置: + - 并发线程数: 100 + - 总交易数: 10000 + - QPS限制: 无限制 + - 预热交易数: 100 + +正在预热 (100 笔交易)... +预热完成! + +开始正式压测... +实时TPS监控 (每5秒更新): + 当前进度: 2145/10000 | 实时TPS: 675.64 | 成功率: 99.87% + 当前进度: 4523/10000 | 实时TPS: 682.31 | 成功率: 99.91% + ... +``` + +--- + +## 结果分析 + +### 📊 测试报告解读 + +测试完成后会自动生成报告(同时保存到文件): + +``` +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 15:30:00 + 结束时间: 2026-02-10 15:32:15 + 测试时长: 135.45 秒 + 并发线程数: 100 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9987 + 失败交易: 13 + 成功率: 99.87% + +性能指标: + ★ TPS (每秒交易数): 675.64 + 平均延迟: 148.23 ms + 中位数延迟: 125 ms + P95延迟: 287 ms + P99延迟: 456 ms + +报告时间: 2026-02-10 15:32:15 +======================================== +``` + +### 📈 核心指标说明 + +#### 1. TPS(每秒交易数) + +**含义:** 每秒成功处理的交易数量 + +**评判标准:** +| TPS范围 | 评价 | 说明 | +|---------|------|------| +| > 1000 | 优秀 ✅ | 性能良好 | +| 500-1000 | 良好 👍 | 基本满足需求 | +| 100-500 | 一般 ⚠️ | 需要优化 | +| < 100 | 较差 ❌ | 存在严重问题 | + +**影响因素:** +- 节点配置(CPU、内存、磁盘) +- 网络延迟 +- 并发线程数 +- 节点 config.ini 配置 + +#### 2. 成功率 + +**含义:** 成功交易数 / 总交易数 + +**评判标准:** +- ✅ ≥ 99%:健康状态 +- ⚠️ 95-99%:压力过大,需降低并发 +- ❌ < 95%:存在严重问题 + +**低成功率原因:** +- 并发数设置过高 +- 交易池容量不足 +- 节点资源不足 +- 账户余额不足 + +#### 3. 延迟指标 + +**平均延迟:** 所有交易的平均响应时间 +**P95延迟:** 95%的交易在此时间内完成 +**P99延迟:** 99%的交易在此时间内完成 + +**评判标准:** +| 指标 | 优秀 | 良好 | 一般 | 需优化 | +|------|------|------|------|--------| +| 平均延迟 | <100ms | 100-300ms | 300-500ms | >500ms | +| P99延迟 | <500ms | 500-1000ms | 1-2s | >2s | + +--- + +## 常见问题排查 + +### ❌ 问题1:TPS很低(<100) + +**可能原因及解决方案:** + +1. **网络延迟过高** + ```bash + # 测试网络延迟 + ping -c 10 121.196.226.157 + ``` + - 延迟 > 100ms:考虑在云服务器上直接运行测试 + - 延迟 > 50ms:TPS会受明显影响 + +2. **节点配置未优化** + + SSH到云服务器检查 `config.ini`: + ```bash + cd ~/fisco/nodes/*/node0 + cat config.ini | grep -A 3 "\[tx_execute\]" + cat config.ini | grep -A 3 "\[consensus\]" + ``` + + 确认配置: + ```ini + [tx_execute] + enable_parallel=true # 必须为true + + [consensus] + max_trans_num_per_block=1000 # 建议≥1000 + ``` + +3. **日志级别过低** + ```ini + [log] + level=error # 改为error减少IO开销 + ``` + +### ❌ 问题2:成功率低(<99%) + +**排查步骤:** + +1. **检查错误日志** + + 测试运行时会输出错误信息: + ``` + 交易失败 - Status: 18, Message: ... + 交易异常: ContractException - ... + ``` + +2. **降低并发数** + + 如果成功率 < 99%,说明并发过高: + ```java + // 从当前并发数降低50% + tester.setTestParams( + 50, // 从100降到50 + 10000, + 0 + ); + ``` + +3. **检查账户余额** + ```bash + cd fisco/console + bash start.sh + # 在控制台执行 + call ParallelTransfer 0x06ac... balanceOf "user_000000" + ``` + +### ❌ 问题3:程序运行时资源耗尽 + +**现象:** 出现大量线程创建失败错误 + +**原因:** 之前的bug(每笔交易创建新合约对象)已修复 + +**确认修复:** 检查代码第29行是否有: +```java +private ParallelTransfer contract; // 复用合约对象 +``` + +### ❌ 问题4:程序一直不退出 + +**原因:** SDK后台线程持续运行 + +**解决:** 已在代码第318行添加: +```java +System.exit(0); +``` + +如果仍然卡住,按 `Ctrl+C` 强制终止。 + +--- + +## 性能优化建议 + +### 🎯 找到准确TPS的方法 + +**错误做法 ❌:** +- 用最高并发数跑一次就认为是TPS +- 忽略成功率指标 +- 测试时间过短(<10秒) + +**正确做法 ✅:** + +#### 阶段1:基准测试 +```java +tester.setTestParams(1, 100, 0); // 单线程 +``` +记录:平均延迟 = X ms + +#### 阶段2:二分法找最佳并发 + +逐步测试,找到成功率≥99%的最大并发数: + +| 轮次 | 并发数 | 交易数 | 观察 | +|------|--------|--------|------| +| 测试1 | 50 | 5000 | 成功率≥99%? | +| 测试2 | 100 | 5000 | 成功率≥99%? | +| 测试3 | 200 | 5000 | 成功率≥99%? | +| 测试4 | 400 | 5000 | 成功率<99%则停止 | + +**结论:** 成功率≥99%的最大并发数 = 最佳并发数 + +#### 阶段3:峰值测试 +```java +tester.setTestParams( + [最佳并发数], // 从阶段2得到 + 50000, // 大批量测试 + 0 +); +``` + +**这就是你链的真实TPS!** + +### 🔧 节点优化Checklist + +#### 云服务器配置 + +SSH到服务器,编辑 `config.ini`: + +```ini +[tx_execute] +enable_parallel=true # ✅ 开启并行 + +[consensus] +max_trans_num_per_block=1000 # ✅ 每块至少1000笔 + +[tx_pool] +limit=150000 # ✅ 交易池容量 + +[log] +level=error # ✅ 降低日志级别 +``` + +重启节点: +```bash +cd ~/fisco/nodes/*/ +bash stop_all.sh +bash start_all.sh +``` + +#### 系统优化 + +```bash +# 增加文件描述符 +ulimit -n 65535 + +# 检查磁盘类型(必须是SSD) +lsblk -d -o name,rota +# rota=0 表示SSD +``` + +### 📊 并发数与TPS的关系 + +**理论公式:** +``` +TPS = 并发数 / 平均延迟(秒) +``` + +**示例:** +- 平均延迟 = 100ms = 0.1秒 +- 并发数 = 100 +- 理论TPS = 100 / 0.1 = **1000** + +**实际调优:** + +| 并发数 | TPS | 成功率 | 决策 | +|--------|-----|--------|------| +| 50 | 400 | 100% | ⬆️ 继续增加 | +| 100 | 700 | 99.8% | ⬆️ 可以继续 | +| 200 | 850 | 99.2% | ⬆️ 接近最佳 | +| 400 | 870 | 97% | ❌ 过高,回退 | + +**最佳并发数 = 200** + +--- + +## 测试结果记录模板 + +建议每次测试记录: + +``` +测试日期: 2026-02-10 +测试轮次: 第X次 + +测试参数: +- 并发线程数: +- 总交易数: +- QPS限制: + +测试环境: +- 节点数量: 4个 +- 网络延迟: XXms +- enable_parallel: true/false +- max_trans_num_per_block: XXX + +测试结果: +- TPS: +- 成功率: +- 平均延迟: +- P99延迟: + +问题记录: + + +优化措施: + + +下次改进: + +``` + +--- + +## 快速参考 + +### 常用命令 + +```bash +# 编译运行测试 +cd /Users/kiro/IdeaProjects/contract +./gradlew build && ./gradlew run + +# 查看最近的测试报告 +ls -lt tps_test_report_*.txt | head -5 +cat tps_test_report_*.txt + +# 测试网络延迟 +ping -c 10 121.196.226.157 + +# 检查节点配置(SSH到服务器) +ssh root@121.196.226.157 +cd ~/fisco/nodes/*/node0 +cat config.ini | grep -E "enable_parallel|max_trans_num_per_block|limit|level" +``` + +### 推荐测试流程 + +```bash +# 1. 基准测试(修改代码为1线程100笔) +./gradlew run + +# 2. 初步压测(修改代码为100线程10000笔) +./gradlew run + +# 3. 根据成功率调整并发数 +# 成功率≥99% → 增加并发 +# 成功率<99% → 减少并发 + +# 4. 峰值测试(用最佳并发数跑50000笔) +./gradlew run +``` + +--- + +## 常见TPS参考值 + +| 区块链 | 单链TPS | 备注 | +|--------|---------|------| +| FISCO BCOS v2.x | 500-2000 | enable_parallel=true | +| FISCO BCOS v3.x | 2000-5000 | 性能优化版 | +| Hyperledger Fabric | 1000-3000 | 企业级联盟链 | +| 以太坊 | 15-30 | 公链 | + +**你的目标:** 根据节点配置,达到 **500-1000 TPS** 即为良好水平。 + +--- + +## 总结 + +### ✅ 正确的测试姿势 + +1. **从小到大测试**:1线程 → 50线程 → 100线程 → 200线程 +2. **关注成功率**:必须≥99%,否则降低并发 +3. **测试足够久**:至少30秒以上 +4. **记录每次结果**:对比优化前后差异 + +### ⚠️ 常见误区 + +1. ❌ 用最高并发测出来的数字就是TPS +2. ❌ 忽略成功率指标 +3. ❌ 测试时间太短 +4. ❌ 不检查节点配置 +5. ❌ 网络延迟过高还在本地测试 + +### 🎯 核心原则 + +**准确的TPS = 在成功率≥99%的前提下,能持续达到的最高TPS** + +--- + +**祝测试顺利!** 🚀 + +有问题请查看"常见问题排查"章节,或检查测试报告中的错误信息。 diff --git a/doc/服务器部署运行指南.md b/doc/服务器部署运行指南.md new file mode 100644 index 0000000..61ea47f --- /dev/null +++ b/doc/服务器部署运行指南.md @@ -0,0 +1,742 @@ +# 服务器部署运行指南 + +> TPS测试工具服务器部署和使用说明 + +--- + +## 📦 打包部署包 + +### 1. 在本地打包 + +```bash +cd /Users/kiro/IdeaProjects/contract + +# 清理并打包(使用 fatJar 任务) +./gradlew clean fatJar + +# 查看生成的 jar 文件 +ls -lh build/libs/tps-test.jar +``` + +**输出:** `build/libs/tps-test.jar` (约 25MB,包含所有依赖) + +**注意:** 必须使用 `./gradlew fatJar` 命令打包,这样才会生成包含所有依赖的可执行jar文件。 + +### 2. 准备部署文件 + +需要上传到服务器的文件: + +``` +部署包/ +├── tps-test.jar # 可执行jar(必需) +└── config.toml # 链连接配置(必需) +``` + +从本地复制配置文件: +```bash +# 复制配置文件到 build 目录 +cp src/main/resources/config.toml build/libs/ +``` + +--- + +## 🚀 上传到服务器 + +### 方法1:使用 SCP 上传 + +```bash +# 1. 创建本地部署目录 +cd /Users/kiro/IdeaProjects/contract +mkdir -p deploy +cp build/libs/tps-test.jar deploy/ +cp src/main/resources/config.toml deploy/ + +# 2. 上传到服务器 +scp -r deploy/* root@121.196.226.157:~/tps-test/ + +# 如果需要上传到第二台服务器 +scp -r deploy/* root@8.137.93.11:~/tps-test/ +``` + +### 方法2:使用 rsync 上传(推荐) + +```bash +# 自动创建目录并上传 +rsync -avz --progress \ + build/libs/tps-test.jar \ + src/main/resources/config.toml \ + root@121.196.226.157:~/tps-test/ +``` + +--- + +## ⚙️ 服务器端配置 + +### 1. SSH 登录到服务器 + +```bash +ssh root@121.196.226.157 +``` + +### 2. 检查 Java 环境 + +```bash +# 检查 Java 版本(需要 JDK 11+) +java -version + +# 如果没有安装,安装 OpenJDK +# Ubuntu/Debian +sudo apt update && sudo apt install -y openjdk-11-jdk + +# CentOS/RHEL +sudo yum install -y java-11-openjdk +``` + +### 3. 验证文件 + +```bash +cd ~/tps-test +ls -lh + +# 应该看到: +# tps-test.jar (约 30-40MB) +# config.toml +``` + +### 4. 修改配置文件(如需要) + +```bash +# 编辑配置文件,确保连接到本地节点 +vim config.toml +``` + +**如果在服务器上运行,建议使用本地地址:** +```toml +[network] +peers=["127.0.0.1:20200"] # 使用本地节点,延迟最低 +``` + +--- + +## 🎯 运行测试 + +### 基本用法 + +```bash +cd ~/tps-test + +# 查看帮助 +java -jar tps-test.jar --help + +# 使用默认参数(100线程,10000笔交易) +java -jar tps-test.jar -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +### 命令行参数说明 + +| 参数 | 简写 | 说明 | 默认值 | +|------|------|------|--------| +| `--threads` | `-t` | 并发线程数 | 100 | +| `--transactions` | `-n` | 总交易数 | 10000 | +| `--qps` | `-q` | QPS限制,0表示不限 | 0 | +| `--contract` | `-c` | **合约地址(必填)** | 无 | +| `--accounts` | `-a` | 测试账户数 | 100 | +| `--help` | `-h` | 显示帮助 | - | + +### 常用测试场景 + +#### 场景1:快速验证(1000笔) + +```bash +java -jar tps-test.jar \ + -t 50 \ + -n 1000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +#### 场景2:标准压测(10000笔) + +```bash +java -jar tps-test.jar \ + -t 100 \ + -n 10000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +#### 场景3:大规模压测(50000笔) + +```bash +java -jar tps-test.jar \ + -t 200 \ + -n 50000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +#### 场景4:极限压测(100000笔) + +```bash +java -jar tps-test.jar \ + -t 500 \ + -n 100000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +#### 场景5:限速测试 + +```bash +# 限制 QPS 为 5000 +java -jar tps-test.jar \ + -t 100 \ + -n 50000 \ + -q 5000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 +``` + +--- + +## 📊 后台运行和日志管理 + +### 1. 后台运行测试 + +```bash +# 使用 nohup 后台运行,输出重定向到日志文件 +nohup java -jar tps-test.jar \ + -t 200 \ + -n 100000 \ + -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 \ + > tps_test.log 2>&1 & + +# 查看进程 +ps aux | grep tps-test + +# 实时查看日志 +tail -f tps_test.log +``` + +### 2. 使用 screen(推荐) + +```bash +# 安装 screen(如果没有) +sudo apt install screen # Ubuntu/Debian +sudo yum install screen # CentOS/RHEL + +# 创建新会话 +screen -S tps-test + +# 运行测试 +java -jar tps-test.jar -t 200 -n 100000 -c 0x06ac... + +# 断开会话(按键):Ctrl+A,然后按 D +# 重新连接:screen -r tps-test +# 查看所有会话:screen -ls +``` + +### 3. 查看测试报告 + +```bash +# 测试完成后,会生成报告文件 +ls -lt tps_test_report_*.txt | head -5 + +# 查看最新报告 +cat $(ls -t tps_test_report_*.txt | head -1) +``` + +--- + +## 🔧 批量测试脚本 + +创建一个自动化测试脚本: + +```bash +# 创建测试脚本 +cat > run_tps_tests.sh << 'EOF' +#!/bin/bash + +# TPS 自动化测试脚本 +CONTRACT="0x06ac2fe406f1ae06494946ee281d58f1c79c39e4" +JAR="tps-test.jar" + +echo "======================================" +echo " FISCO BCOS TPS 自动化测试" +echo "======================================" +echo "" + +# 测试配置数组(线程数 交易数 描述) +tests=( + "50:5000:快速验证" + "100:10000:基础压测" + "200:10000:中等压测" + "400:10000:高并发压测" +) + +# 循环执行测试 +for test in "${tests[@]}"; do + IFS=':' read -r threads txs desc <<< "$test" + + echo "" + echo "======================================" + echo "测试: $desc" + echo "并发数: $threads, 交易数: $txs" + echo "======================================" + echo "" + + java -jar $JAR -t $threads -n $txs -c $CONTRACT + + echo "" + echo "等待10秒后开始下一轮测试..." + sleep 10 +done + +echo "" +echo "======================================" +echo "所有测试完成!" +echo "======================================" + +# 汇总报告 +echo "" +echo "测试报告列表:" +ls -lt tps_test_report_*.txt | head -10 +EOF + +# 给脚本添加执行权限 +chmod +x run_tps_tests.sh + +# 运行自动化测试 +./run_tps_tests.sh +``` + +--- + +## 📈 分阶段找准确TPS的脚本 + +基于文档中推荐的测试方法: + +```bash +cat > find_optimal_tps.sh << 'EOF' +#!/bin/bash + +# 二分法找最佳TPS脚本 +CONTRACT="0x06ac2fe406f1ae06494946ee281d58f1c79c39e4" +JAR="tps-test.jar" + +echo "======================================" +echo " 寻找最佳 TPS 配置" +echo "======================================" +echo "" + +# 阶段1:基准测试 +echo "[阶段1] 基准测试(单线程)" +java -jar $JAR -t 1 -n 100 -c $CONTRACT +echo "" +read -p "按 Enter 继续..." + +# 阶段2:逐步增加并发 +threads_list=(50 100 200 400) + +for threads in "${threads_list[@]}"; do + echo "" + echo "======================================" + echo "[阶段2] 测试 $threads 线程" + echo "======================================" + echo "" + + java -jar $JAR -t $threads -n 5000 -c $CONTRACT + + echo "" + read -p "成功率是否 ≥99%?(y/n): " answer + + if [ "$answer" != "y" ]; then + echo "成功率低于99%,建议使用上一个并发数" + last_good=$((threads / 2)) + echo "建议最佳并发数: $last_good" + + echo "" + read -p "是否用最佳并发数运行峰值测试?(y/n): " peak_test + + if [ "$peak_test" = "y" ]; then + echo "" + echo "======================================" + echo "[阶段3] 峰值测试" + echo "======================================" + echo "" + java -jar $JAR -t $last_good -n 50000 -c $CONTRACT + fi + + break + fi +done + +echo "" +echo "======================================" +echo "测试完成!" +echo "======================================" +EOF + +chmod +x find_optimal_tps.sh +./find_optimal_tps.sh +``` + +--- + +## 🔍 监控和诊断 + +### 1. 实时监控测试进程 + +```bash +# 监控 CPU 和内存 +top -p $(pgrep -f tps-test.jar) + +# 监控网络连接 +watch -n 1 'netstat -antp | grep 20200' +``` + +### 2. 查看节点日志 + +```bash +# 查看节点日志 +tail -f ~/fisco/nodes/*/node0/log/log* | grep -E "ERROR|TPS" + +# 查看交易池状态 +cd ~/fisco/console +bash start.sh +# 执行:getPendingTxSize +``` + +### 3. 系统资源监控 + +```bash +# 整体系统监控 +htop + +# 磁盘 IO +iostat -x 1 + +# 网络流量 +iftop -i eth0 +``` + +--- + +## ⚠️ 常见问题 + +### 问题1:找不到或无法加载主类 + +**错误信息:** +``` +Error: Could not find or load main class com.org.fisco.TPSTest +``` + +**原因:** jar文件打包不正确,缺少依赖类 + +**解决:** +```bash +# 1. 必须使用 fatJar 任务打包 +cd /Users/kiro/IdeaProjects/contract +./gradlew clean fatJar + +# 2. 验证jar文件可以运行 +java -jar build/libs/tps-test.jar --help + +# 3. 重新上传到服务器 +scp build/libs/tps-test.jar root@服务器IP:~/tps-test/ +``` + +**注意:** 不要使用 `./gradlew build`,必须使用 `./gradlew fatJar` + +### 问题2:找不到 config.toml + +**错误信息:** +``` +错误: 找不到配置文件 config.toml +``` + +**解决:** +```bash +# 确保 config.toml 在当前目录 +cd ~/tps-test +ls config.toml + +# 或者从 console 复制 +cp ~/fisco/console/conf/config.toml . +``` + +### 问题3:连接节点失败 + +**错误信息:** +``` +连接FISCO BCOS节点失败 +``` + +**解决:** +```bash +# 1. 检查节点是否运行 +ps aux | grep fisco-bcos + +# 2. 检查端口是否监听 +netstat -tlnp | grep 20200 + +# 3. 测试连接 +telnet 127.0.0.1 20200 + +# 4. 修改 config.toml 使用正确的地址 +vim config.toml +``` + +### 问题4:内存不足 + +**错误信息:** +``` +java.lang.OutOfMemoryError +``` + +**解决:** +```bash +# 增加 JVM 内存 +java -Xmx4g -Xms2g -jar tps-test.jar -t 200 -n 50000 -c 0x06ac... +``` + +### 问题5:程序卡住不动 + +**排查:** +```bash +# 1. 查看是否有错误日志 +tail -100 tps_test.log + +# 2. 检查网络连接 +netstat -antp | grep 20200 + +# 3. 检查节点是否正常 +cd ~/fisco/nodes/*/node0 +tail -50 log/log* +``` + +--- + +## 🎯 最佳实践 + +### 1. 在服务器上测试的优势 + +✅ **延迟更低**:本地网络延迟通常 < 1ms +✅ **TPS更高**:网络不是瓶颈 +✅ **结果更准**:排除网络抖动影响 + +### 2. 推荐的测试流程 + +```bash +# 第一步:快速验证 +java -jar tps-test.jar -t 50 -n 1000 -c 0x06ac... + +# 第二步:基础测试 +java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac... + +# 第三步:根据成功率调整 +# 如果成功率 ≥ 99%,增加并发到 200 +# 如果成功率 < 99%,保持或降低并发 + +# 第四步:峰值测试 +java -jar tps-test.jar -t [最佳并发] -n 50000 -c 0x06ac... +``` + +### 3. 参数选择建议 + +| 节点配置 | 推荐并发数 | 推荐交易数 | +|---------|----------|----------| +| 2C4G | 50-100 | 10000 | +| 4C8G | 100-200 | 50000 | +| 8C16G | 200-500 | 100000 | + +--- + +## 📝 测试记录模板 + +建议每次测试记录: + +```bash +# 创建测试记录文件 +cat > test_record_$(date +%Y%m%d).md << 'EOF' +# TPS测试记录 + +## 测试日期 +2026-02-10 + +## 测试环境 +- 服务器: 121.196.226.157 +- 节点配置: 4C8G SSD +- enable_parallel: true +- max_trans_num_per_block: 1000 + +## 测试结果 + +### 测试1 +- 命令: java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac... +- TPS: +- 成功率: +- 平均延迟: + +### 测试2 +- 命令: +- TPS: +- 成功率: +- 平均延迟: + +## 结论 +最佳并发数: +峰值TPS: + +## 优化建议 + +EOF + +vim test_record_$(date +%Y%m%d).md +``` + +--- + +## 🔄 更新部署 + +当代码有更新时: + +```bash +# 本地重新打包 +cd /Users/kiro/IdeaProjects/contract +./gradlew clean fatJar + +# 验证jar可以运行 +java -jar build/libs/tps-test.jar --help + +# 上传到服务器(覆盖旧版本) +scp build/libs/tps-test.jar root@121.196.226.157:~/tps-test/ + +# 服务器上重新运行测试 +ssh root@121.196.226.157 +cd ~/tps-test +java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac... +``` + +--- + +## 📞 快速命令参考 + +```bash +# 本地打包 +cd /Users/kiro/IdeaProjects/contract +./gradlew clean fatJar + +# 验证打包(本地测试) +java -jar build/libs/tps-test.jar --help + +# 上传到服务器 +scp build/libs/tps-test.jar src/main/resources/config.toml root@121.196.226.157:~/tps-test/ + +# SSH到服务器运行 +ssh root@121.196.226.157 +cd ~/tps-test + +# 测试帮助 +java -jar tps-test.jar --help + +# 运行测试 +java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 + +# 查看报告 +cat $(ls -t tps_test_report_*.txt | head -1) +``` + +--- + +## 🎓 完整部署示例 + +### 从零开始的完整流程 + +```bash +# ======================================== +# 第一步:在本地打包 +# ======================================== +cd /Users/kiro/IdeaProjects/contract + +# 清理并打包 +./gradlew clean fatJar + +# 验证jar文件 +java -jar build/libs/tps-test.jar --help +# 应该显示帮助信息,如果报错说明打包有问题 + + +# ======================================== +# 第二步:准备部署文件 +# ======================================== +mkdir -p deploy +cp build/libs/tps-test.jar deploy/ +cp src/main/resources/config.toml deploy/ + +# 查看文件 +ls -lh deploy/ +# 应该看到: +# tps-test.jar (约 25MB) +# config.toml + + +# ======================================== +# 第三步:上传到服务器 +# ======================================== +# 方式1:使用 scp +scp deploy/tps-test.jar deploy/config.toml root@121.196.226.157:~/tps-test/ + +# 方式2:使用 rsync(推荐) +rsync -avz --progress deploy/* root@121.196.226.157:~/tps-test/ + + +# ======================================== +# 第四步:SSH到服务器配置 +# ======================================== +ssh root@121.196.226.157 + +# 进入目录 +cd ~/tps-test + +# 检查文件 +ls -lh +# 应该看到 tps-test.jar 和 config.toml + +# 检查Java版本(需要JDK 11+) +java -version + +# 编辑配置文件,使用本地节点地址 +vim config.toml +# 修改为:peers=["127.0.0.1:20200"] + +# 测试jar文件 +java -jar tps-test.jar --help +# 应该显示帮助信息 + + +# ======================================== +# 第五步:运行测试 +# ======================================== + +# 快速验证(1000笔) +java -jar tps-test.jar -t 50 -n 1000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 + +# 如果上面的测试成功,运行正式测试 +java -jar tps-test.jar -t 100 -n 10000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4 + +# 查看生成的报告 +cat $(ls -t tps_test_report_*.txt | head -1) +``` + +--- + +## 🔍 验证清单 + +部署后请按此清单验证: + +- [ ] jar文件大小约25MB(太小说明没打包依赖) +- [ ] 本地能运行 `java -jar build/libs/tps-test.jar --help` +- [ ] 服务器上能显示帮助信息 +- [ ] config.toml 配置了正确的节点地址 +- [ ] 能连接到节点(显示区块高度) +- [ ] 测试能正常运行并生成报告 + +--- + +**祝测试顺利!** 🚀 diff --git a/src/main/java/com/org/fisco/ParallelTransfer.java b/src/main/java/com/org/fisco/ParallelTransfer.java new file mode 100644 index 0000000..a808ed1 --- /dev/null +++ b/src/main/java/com/org/fisco/ParallelTransfer.java @@ -0,0 +1,252 @@ +package org.com.fisco; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.fisco.bcos.sdk.abi.FunctionReturnDecoder; +import org.fisco.bcos.sdk.abi.TypeReference; +import org.fisco.bcos.sdk.abi.datatypes.Bool; +import org.fisco.bcos.sdk.abi.datatypes.Event; +import org.fisco.bcos.sdk.abi.datatypes.Function; +import org.fisco.bcos.sdk.abi.datatypes.Type; +import org.fisco.bcos.sdk.abi.datatypes.Utf8String; +import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256; +import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1; +import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple2; +import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple3; +import org.fisco.bcos.sdk.client.Client; +import org.fisco.bcos.sdk.contract.Contract; +import org.fisco.bcos.sdk.crypto.CryptoSuite; +import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.eventsub.EventCallback; +import org.fisco.bcos.sdk.model.CryptoType; +import org.fisco.bcos.sdk.model.TransactionReceipt; +import org.fisco.bcos.sdk.model.callback.TransactionCallback; +import org.fisco.bcos.sdk.transaction.model.exception.ContractException; + +@SuppressWarnings("unchecked") +public class ParallelTransfer extends Contract { + public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b5061067f806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806335ee5f871461005c5780638a42ebe9146100d95780639b80b05014610164575b600080fd5b34801561006857600080fd5b506100c3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610235565b6040518082815260200191505060405180910390f35b3480156100e557600080fd5b5061014a600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506102a9565b604051808215151515815260200191505060405180910390f35b34801561017057600080fd5b5061021b600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001909291905050506103c9565b604051808215151515815260200191505060405180910390f35b600080826040518082805190602001908083835b60208310151561026e5780518252602082019150602081019050602083039250610249565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000816000846040518082805190602001908083835b6020831015156102e457805182526020820191506020810190506020830392506102bf565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020819055507fedf5e4fbc41240253887c57b73bdead5653cd408f92653efbb6cb02835878f1d83836040518080602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610384578082015181840152602081019050610369565b50505050905090810190601f1680156103b15780820380516001836020036101000a031916815260200191505b50935050505060405180910390a16001905092915050565b6000816000856040518082805190602001908083835b60208310151561040457805182526020820191506020810190506020830392506103df565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020541015151561044557600080fd5b816000856040518082805190602001908083835b60208310151561047e5780518252602082019150602081019050602083039250610459565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540392505081905550816000846040518082805190602001908083835b6020831015156104f757805182526020820191506020810190506020830392506104d2565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825401925050819055507f0330d309c76066247312f39e9d58dd5b00d4746f169284ac6e3835f6ea07484b848484604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156105a557808201518184015260208101905061058a565b50505050905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561060b5780820151818401526020810190506105f0565b50505050905090810190601f1680156106385780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a16001905093925050505600a165627a7a723058201e9804ebdeb9c0397abfc6f7eeadb97d2565b57eb91245f4864623800f25aa2e0029"}; + + public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY); + + public static final String[] SM_BINARY_ARRAY = {"608060405234801561001057600080fd5b5061067f806100206000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063612d2bff1461005c578063cd93c25d1461012d578063f2f4ee6d146101aa575b600080fd5b34801561006857600080fd5b50610113600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610235565b604051808215151515815260200191505060405180910390f35b34801561013957600080fd5b50610194600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506104bf565b6040518082815260200191505060405180910390f35b3480156101b657600080fd5b5061021b600480360381019080803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929080359060200190929190505050610533565b604051808215151515815260200191505060405180910390f35b6000816000856040518082805190602001908083835b602083101515610270578051825260208201915060208101905060208303925061024b565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902054101515156102b157600080fd5b816000856040518082805190602001908083835b6020831015156102ea57805182526020820191506020810190506020830392506102c5565b6001836020036101000a038019825116818451168082178552505050505050905001915050908152602001604051809103902060008282540392505081905550816000846040518082805190602001908083835b602083101515610363578051825260208201915060208101905060208303925061033e565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020600082825401925050819055507fc2a2916bcd9b97e315313bf3748b5c215a3a399633f7d1cde7b55db8e500c784848484604051808060200180602001848152602001838103835286818151815260200191508051906020019080838360005b838110156104115780820151818401526020810190506103f6565b50505050905090810190601f16801561043e5780820380516001836020036101000a031916815260200191505b50838103825285818151815260200191508051906020019080838360005b8381101561047757808201518184015260208101905061045c565b50505050905090810190601f1680156104a45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600190509392505050565b600080826040518082805190602001908083835b6020831015156104f857805182526020820191506020810190506020830392506104d3565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020549050919050565b6000816000846040518082805190602001908083835b60208310151561056e5780518252602082019150602081019050602083039250610549565b6001836020036101000a0380198251168184511680821785525050505050509050019150509081526020016040518091039020819055507f0596d2b9710318c05b80b92422c73d44ef236e2d1e4f7c6f9122213d2d21216083836040518080602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561060e5780820151818401526020810190506105f3565b50505050905090810190601f16801561063b5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a160019050929150505600a165627a7a72305820e98be5dd9ae36682f9e427b573d5a836e23a6a087c94d68f7bc42e7e432559840029"}; + + public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY); + + public static final String[] ABI_ARRAY = {"[{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"string\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"string\"},{\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"from\",\"type\":\"string\"},{\"name\":\"to\",\"type\":\"string\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"from\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"to\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TransferEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"user\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"balance\",\"type\":\"uint256\"}],\"name\":\"SetEvent\",\"type\":\"event\"}]"}; + + public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY); + + public static final String FUNC_BALANCEOF = "balanceOf"; + + public static final String FUNC_SET = "set"; + + public static final String FUNC_TRANSFER = "transfer"; + + public static final Event TRANSFEREVENT_EVENT = new Event("TransferEvent", + Arrays.>asList(new TypeReference() {}, new TypeReference() {}, new TypeReference() {})); + ; + + public static final Event SETEVENT_EVENT = new Event("SetEvent", + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + ; + + protected ParallelTransfer(String contractAddress, Client client, CryptoKeyPair credential) { + super(getBinary(client.getCryptoSuite()), contractAddress, client, credential); + } + + public static String getBinary(CryptoSuite cryptoSuite) { + return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY); + } + + public BigInteger balanceOf(String user) throws ContractException { + final Function function = new Function(FUNC_BALANCEOF, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user)), + Arrays.>asList(new TypeReference() {})); + return executeCallWithSingleValueReturn(function, BigInteger.class); + } + + public TransactionReceipt set(String user, BigInteger balance) { + final Function function = new Function( + FUNC_SET, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)), + Collections.>emptyList()); + return executeTransaction(function); + } + + public byte[] set(String user, BigInteger balance, TransactionCallback callback) { + final Function function = new Function( + FUNC_SET, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)), + Collections.>emptyList()); + return asyncExecuteTransaction(function, callback); + } + + public String getSignedTransactionForSet(String user, BigInteger balance) { + final Function function = new Function( + FUNC_SET, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(user), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(balance)), + Collections.>emptyList()); + return createSignedTransaction(function); + } + + public Tuple2 getSetInput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getInput().substring(10); + final Function function = new Function(FUNC_SET, + Arrays.asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {})); + List results = FunctionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple2( + + (String) results.get(0).getValue(), + (BigInteger) results.get(1).getValue() + ); + } + + public Tuple1 getSetOutput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getOutput(); + final Function function = new Function(FUNC_SET, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + List results = FunctionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple1( + + (Boolean) results.get(0).getValue() + ); + } + + public TransactionReceipt transfer(String from, String to, BigInteger amount) { + final Function function = new Function( + FUNC_TRANSFER, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from), + new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)), + Collections.>emptyList()); + return executeTransaction(function); + } + + public byte[] transfer(String from, String to, BigInteger amount, TransactionCallback callback) { + final Function function = new Function( + FUNC_TRANSFER, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from), + new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)), + Collections.>emptyList()); + return asyncExecuteTransaction(function, callback); + } + + public String getSignedTransactionForTransfer(String from, String to, BigInteger amount) { + final Function function = new Function( + FUNC_TRANSFER, + Arrays.asList(new org.fisco.bcos.sdk.abi.datatypes.Utf8String(from), + new org.fisco.bcos.sdk.abi.datatypes.Utf8String(to), + new org.fisco.bcos.sdk.abi.datatypes.generated.Uint256(amount)), + Collections.>emptyList()); + return createSignedTransaction(function); + } + + public Tuple3 getTransferInput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getInput().substring(10); + final Function function = new Function(FUNC_TRANSFER, + Arrays.asList(), + Arrays.>asList(new TypeReference() {}, new TypeReference() {}, new TypeReference() {})); + List results = FunctionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple3( + + (String) results.get(0).getValue(), + (String) results.get(1).getValue(), + (BigInteger) results.get(2).getValue() + ); + } + + public Tuple1 getTransferOutput(TransactionReceipt transactionReceipt) { + String data = transactionReceipt.getOutput(); + final Function function = new Function(FUNC_TRANSFER, + Arrays.asList(), + Arrays.>asList(new TypeReference() {})); + List results = FunctionReturnDecoder.decode(data, function.getOutputParameters()); + return new Tuple1( + + (Boolean) results.get(0).getValue() + ); + } + + public List getTransferEventEvents(TransactionReceipt transactionReceipt) { + List valueList = extractEventParametersWithLog(TRANSFEREVENT_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + TransferEventEventResponse typedResponse = new TransferEventEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse.from = (String) eventValues.getNonIndexedValues().get(0).getValue(); + typedResponse.to = (String) eventValues.getNonIndexedValues().get(1).getValue(); + typedResponse.amount = (BigInteger) eventValues.getNonIndexedValues().get(2).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public void subscribeTransferEventEvent(String fromBlock, String toBlock, List otherTopics, EventCallback callback) { + String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT); + subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback); + } + + public void subscribeTransferEventEvent(EventCallback callback) { + String topic0 = eventEncoder.encode(TRANSFEREVENT_EVENT); + subscribeEvent(ABI,BINARY,topic0,callback); + } + + public List getSetEventEvents(TransactionReceipt transactionReceipt) { + List valueList = extractEventParametersWithLog(SETEVENT_EVENT, transactionReceipt); + ArrayList responses = new ArrayList(valueList.size()); + for (Contract.EventValuesWithLog eventValues : valueList) { + SetEventEventResponse typedResponse = new SetEventEventResponse(); + typedResponse.log = eventValues.getLog(); + typedResponse.user = (String) eventValues.getNonIndexedValues().get(0).getValue(); + typedResponse.balance = (BigInteger) eventValues.getNonIndexedValues().get(1).getValue(); + responses.add(typedResponse); + } + return responses; + } + + public void subscribeSetEventEvent(String fromBlock, String toBlock, List otherTopics, EventCallback callback) { + String topic0 = eventEncoder.encode(SETEVENT_EVENT); + subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback); + } + + public void subscribeSetEventEvent(EventCallback callback) { + String topic0 = eventEncoder.encode(SETEVENT_EVENT); + subscribeEvent(ABI,BINARY,topic0,callback); + } + + public static ParallelTransfer load(String contractAddress, Client client, CryptoKeyPair credential) { + return new ParallelTransfer(contractAddress, client, credential); + } + + public static ParallelTransfer deploy(Client client, CryptoKeyPair credential) throws ContractException { + return deploy(ParallelTransfer.class, client, credential, getBinary(client.getCryptoSuite()), ""); + } + + public static class TransferEventEventResponse { + public TransactionReceipt.Logs log; + + public String from; + + public String to; + + public BigInteger amount; + } + + public static class SetEventEventResponse { + public TransactionReceipt.Logs log; + + public String user; + + public BigInteger balance; + } +} diff --git a/src/main/java/com/org/fisco/TPSTest.java b/src/main/java/com/org/fisco/TPSTest.java new file mode 100644 index 0000000..7fbe0cc --- /dev/null +++ b/src/main/java/com/org/fisco/TPSTest.java @@ -0,0 +1,436 @@ +package com.org.fisco; + +import org.fisco.bcos.sdk.BcosSDK; +import org.fisco.bcos.sdk.client.Client; +import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.model.TransactionReceipt; +import org.com.fisco.ParallelTransfer; // 导入ParallelTransfer合约类 + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * FISCO BCOS TPS压力测试工具 + * + * 使用方法: + * 1. 先部署合约: TPSTest.deployContract() + * 2. 初始化账户: TPSTest.initAccounts() + * 3. 运行压测: TPSTest.runStressTest() + */ +public class TPSTest { + + private BcosSDK sdk; + private Client client; + private String contractAddress; + private ParallelTransfer contract; // 复用合约对象,避免每次都创建 + + // 测试配置 + private int threadCount = 20; // 并发线程数 + private int totalTransactions = 100000; // 总交易数 + private int qpsLimit = 0; // QPS限制,0表示不限制 + private int warmupTransactions = 100; // 预热交易数 + + // 账户池 + private List accountPool = new ArrayList<>(); + private AtomicInteger accountIndex = new AtomicInteger(0); + + public TPSTest(String configFile) throws Exception { + this.sdk = BcosSDK.build(configFile); + this.client = sdk.getClient(1); // v2.x使用群组ID数字,默认群组1 + System.out.println("连接FISCO BCOS节点成功"); + System.out.println("当前区块高度: " + client.getBlockNumber()); + } + + /** + * 设置测试参数 + */ + public void setTestParams(int threadCount, int totalTransactions, int qpsLimit) { + this.threadCount = threadCount; + this.totalTransactions = totalTransactions; + this.qpsLimit = qpsLimit; + } + + /** + * 步骤1: 部署压测合约 + */ + public String deployContract() throws Exception { + System.out.println("\n[1/3] 部署ParallelTransfer合约..."); + + CryptoKeyPair keyPair = client.getCryptoSuite().getCryptoKeyPair(); + + // 注意: 需要先使用控制台编译合约生成Java类 + // 这里假设已经生成了ParallelTransfer.java + // ParallelTransfer contract = ParallelTransfer.deploy(client, keyPair); + // this.contractAddress = contract.getContractAddress(); + + // 如果手动已经部署,可以直接设置地址 + this.contractAddress = "0x06ac2fe406f1ae06494946ee281d58f1c79c39e4"; + + System.out.println("合约部署成功!"); + System.out.println("合约地址: " + contractAddress); + + return contractAddress; + } + + /** + * 步骤2: 初始化测试账户 + */ + public void initAccounts(int accountCount) { + System.out.println("\n[2/3] 初始化测试账户..."); + System.out.println("生成 " + accountCount + " 个测试账户..."); + + for (int i = 0; i < accountCount; i++) { + accountPool.add("user_" + String.format("%06d", i)); + } + + System.out.println("账户初始化完成! 账户数: " + accountPool.size()); + } + + /** + * 生成账户列表(不初始化余额,用于已通过脚本初始化的场景) + */ + public void generateAccountList(int accountCount) { + for (int i = 0; i < accountCount; i++) { + accountPool.add("user_" + String.format("%06d", i)); + } + System.out.println("已生成 " + accountPool.size() + " 个测试账户"); + } + + /** + * 步骤3: 运行压力测试 + */ + public TPSTestResult runStressTest() throws Exception { + System.out.println("\n[3/3] 开始压力测试..."); + System.out.println("测试配置:"); + System.out.println(" - 并发线程数: " + threadCount); + System.out.println(" - 总交易数: " + totalTransactions); + System.out.println(" - QPS限制: " + (qpsLimit > 0 ? qpsLimit : "无限制")); + System.out.println(" - 预热交易数: " + warmupTransactions); + + TPSTestResult result = new TPSTestResult(threadCount, qpsLimit); + + // 预热 + if (warmupTransactions > 0) { + System.out.println("\n正在预热 (" + warmupTransactions + " 笔交易)..."); + runTestPhase(warmupTransactions, result, true); + System.out.println("预热完成!"); + } + + // 正式测试 + System.out.println("\n开始正式压测..."); + System.out.println("实时TPS监控 (每5秒更新):"); + + // 重置统计 + TPSTestResult finalResult = new TPSTestResult(threadCount, qpsLimit); + final int finalTotalTx = totalTransactions; + + // 启动监控线程 + ScheduledExecutorService monitor = Executors.newScheduledThreadPool(1); + monitor.scheduleAtFixedRate(() -> { + System.out.printf(" 当前进度: %d/%d | 实时TPS: %.2f | 成功率: %.2f%%\n", + finalResult.getTotalTransactions(), finalTotalTx, + finalResult.getRealtimeTPS(), finalResult.calculateSuccessRate()); + }, 5, 5, TimeUnit.SECONDS); + + // 执行测试 + runTestPhase(totalTransactions, finalResult, false); + + // 停止监控 + monitor.shutdown(); + + finalResult.markEnd(); + + return finalResult; + } + + /** + * 执行测试阶段 + */ + private void runTestPhase(int txCount, TPSTestResult result, boolean isWarmup) throws Exception { + ExecutorService executor = Executors.newFixedThreadPool(threadCount); + CountDownLatch latch = new CountDownLatch(txCount); + + // QPS限流器 + Semaphore rateLimiter = qpsLimit > 0 ? new Semaphore(qpsLimit) : null; + + if (qpsLimit > 0) { + // 启动令牌补充线程 + ScheduledExecutorService refiller = Executors.newScheduledThreadPool(1); + refiller.scheduleAtFixedRate(() -> { + int available = rateLimiter.availablePermits(); + if (available < qpsLimit) { + rateLimiter.release(qpsLimit - available); + } + }, 0, 1, TimeUnit.SECONDS); + } + + Random random = new Random(); + + // 提交所有交易任务 + for (int i = 0; i < txCount; i++) { + executor.submit(() -> { + try { + // QPS限流 + if (rateLimiter != null) { + rateLimiter.acquire(); + } + + long startTime = System.currentTimeMillis(); + + // 随机选择两个账户进行转账 + String fromAccount = getRandomAccount(); + String toAccount = getRandomAccount(); + int amount = random.nextInt(100) + 1; + + // 发送交易 + boolean success = sendTransferTransaction(fromAccount, toAccount, amount); + + long endTime = System.currentTimeMillis(); + long latency = endTime - startTime; + + if (!isWarmup) { + if (success) { + result.recordSuccess(latency); + } else { + result.recordFailure("交易执行失败"); + } + } + + } catch (Exception e) { + if (!isWarmup) { + result.recordFailure(e.getMessage()); + } + } finally { + latch.countDown(); + } + }); + } + + // 等待所有交易完成 + latch.await(); + executor.shutdown(); + executor.awaitTermination(10, TimeUnit.MINUTES); + } + + /** + * 初始化合约对象(只调用一次) + */ + private void initContract() throws Exception { + CryptoKeyPair keyPair = client.getCryptoSuite().getCryptoKeyPair(); + this.contract = ParallelTransfer.load(contractAddress, client, keyPair); + System.out.println("合约对象初始化完成"); + } + + /** + * 发送转账交易(复用contract对象) + */ + private boolean sendTransferTransaction(String from, String to, int amount) { + try { + TransactionReceipt receipt = contract.transfer(from, to, BigInteger.valueOf(amount)); + if (!receipt.isStatusOK()) { + System.err.println("交易失败 - Status: " + receipt.getStatus() + + ", Message: " + receipt.getMessage()); + } + return receipt.isStatusOK(); + } catch (Exception e) { + System.err.println("交易异常: " + e.getClass().getSimpleName() + " - " + e.getMessage()); + return false; + } + } + + /** + * 随机获取一个账户 + */ + private String getRandomAccount() { + int index = accountIndex.getAndIncrement() % accountPool.size(); + return accountPool.get(index); + } + + /** + * 关闭连接 + */ + public void close() { + // SDK 2.x不需要显式关闭,会自动清理资源 + // 如果需要,可以让JVM自动回收 + } + + /** + * 打印使用帮助 + */ + private static void printUsage() { + System.out.println("用法: java -jar tps-test.jar [选项]"); + System.out.println(); + System.out.println("选项:"); + System.out.println(" -t, --threads <数量> 并发线程数 (默认: 100)"); + System.out.println(" -n, --transactions <数量> 总交易数 (默认: 10000)"); + System.out.println(" -q, --qps <限制> QPS限制,0表示不限制 (默认: 0)"); + System.out.println(" -c, --contract <地址> 合约地址 (必填)"); + System.out.println(" -a, --accounts <数量> 测试账户数 (默认: 100)"); + System.out.println(" -h, --help 显示此帮助信息"); + System.out.println(); + System.out.println("示例:"); + System.out.println(" # 使用默认参数"); + System.out.println(" java -jar tps-test.jar -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4"); + System.out.println(); + System.out.println(" # 自定义参数"); + System.out.println(" java -jar tps-test.jar -t 200 -n 50000 -c 0x06ac2fe406f1ae06494946ee281d58f1c79c39e4"); + System.out.println(); + System.out.println(" # 使用 gradlew 运行"); + System.out.println(" ./gradlew run --args=\"-t 200 -n 50000 -c 0x06ac...\""); + } + + /** + * 主测试流程(支持命令行参数) + */ + public static void main(String[] args) { + TPSTest tester = null; + try { + // 解析命令行参数 + int threadCount = 100; // 默认并发数 + int totalTransactions = 10000; // 默认交易总数 + int qpsLimit = 0; // 默认不限速 + String contractAddress = null; // 合约地址(必填) + int accountCount = 100; // 默认账户数 + + // 解析参数 + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + + if (arg.equals("-h") || arg.equals("--help")) { + printUsage(); + return; + } + + if (i + 1 < args.length) { + String value = args[i + 1]; + + switch (arg) { + case "-t": + case "--threads": + threadCount = Integer.parseInt(value); + i++; + break; + case "-n": + case "--transactions": + totalTransactions = Integer.parseInt(value); + i++; + break; + case "-q": + case "--qps": + qpsLimit = Integer.parseInt(value); + i++; + break; + case "-c": + case "--contract": + contractAddress = value; + i++; + break; + case "-a": + case "--accounts": + accountCount = Integer.parseInt(value); + i++; + break; + default: + System.err.println("未知参数: " + arg); + printUsage(); + System.exit(1); + } + } + } + + // 验证必填参数 + if (contractAddress == null || contractAddress.isEmpty()) { + System.err.println("错误: 必须指定合约地址 (-c 或 --contract)"); + System.err.println(); + printUsage(); + System.exit(1); + } + + // 验证参数范围 + if (threadCount <= 0 || threadCount > 10000) { + System.err.println("错误: 并发线程数必须在 1-10000 之间"); + System.exit(1); + } + if (totalTransactions <= 0) { + System.err.println("错误: 交易总数必须大于 0"); + System.exit(1); + } + + System.out.println("========================================"); + System.out.println(" FISCO BCOS TPS压力测试工具"); + System.out.println("========================================\n"); + + System.out.println("测试参数:"); + System.out.println(" 并发线程数: " + threadCount); + System.out.println(" 总交易数: " + totalTransactions); + System.out.println(" QPS限制: " + (qpsLimit > 0 ? qpsLimit : "无限制")); + System.out.println(" 合约地址: " + contractAddress); + System.out.println(" 测试账户数: " + accountCount); + System.out.println(); + + // 1. 初始化(支持从当前目录或resources目录读取配置) + String configFile = "config.toml"; + if (!new java.io.File(configFile).exists()) { + configFile = "src/main/resources/config.toml"; + } + if (!new java.io.File(configFile).exists()) { + System.err.println("错误: 找不到配置文件 config.toml"); + System.err.println("请确保当前目录或 src/main/resources/ 目录下有 config.toml 文件"); + System.exit(1); + } + + tester = new TPSTest(configFile); + + // 2. 设置测试参数 + tester.setTestParams(threadCount, totalTransactions, qpsLimit); + + // 3. 设置合约地址 + tester.contractAddress = contractAddress; + System.out.println("使用合约地址: " + tester.contractAddress); + + // 4. 初始化合约对象(重要:只创建一次,避免资源泄漏) + tester.initContract(); + + // 5. 生成测试账户列表(账户余额已通过脚本初始化) + System.out.println("\n生成测试账户列表..."); + tester.generateAccountList(accountCount); + System.out.println("账户列表生成完成,账户余额应已通过 init_accounts.sh 脚本初始化"); + + // 6. 运行压测 + TPSTestResult result = tester.runStressTest(); + + // 7. 输出报告 + System.out.println("\n" + result.generateReport()); + + // 8. 保存报告到文件 + String reportFile = "tps_test_report_" + System.currentTimeMillis() + ".txt"; + java.nio.file.Files.write( + java.nio.file.Paths.get(reportFile), + result.generateReport().getBytes() + ); + System.out.println("测试报告已保存到: " + reportFile); + + } catch (NumberFormatException e) { + System.err.println("错误: 参数格式不正确"); + System.err.println(e.getMessage()); + printUsage(); + System.exit(1); + } catch (Exception e) { + System.err.println("测试失败: " + e.getMessage()); + e.printStackTrace(); + System.exit(1); + } finally { + if (tester != null) { + tester.close(); + } + // 强制退出程序,避免SDK的后台线程一直运行 + System.out.println("\n测试完成,退出程序..."); + System.exit(0); + } + } +} + diff --git a/src/main/java/com/org/fisco/TPSTestResult.java b/src/main/java/com/org/fisco/TPSTestResult.java new file mode 100644 index 0000000..49319ad --- /dev/null +++ b/src/main/java/com/org/fisco/TPSTestResult.java @@ -0,0 +1,184 @@ +package com.org.fisco; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * TPS测试结果统计类 + */ +public class TPSTestResult { + + private long startTime; + private long endTime; + private int threadCount; + private int qpsLimit; + + // 交易统计 + private AtomicInteger totalTransactions = new AtomicInteger(0); + private AtomicInteger successTransactions = new AtomicInteger(0); + private AtomicInteger failedTransactions = new AtomicInteger(0); + + // 延迟统计 + private List latencies = Collections.synchronizedList(new ArrayList<>()); + private AtomicLong totalLatency = new AtomicLong(0); + + // 错误信息 + private List errors = Collections.synchronizedList(new ArrayList<>()); + + public TPSTestResult(int threadCount, int qpsLimit) { + this.threadCount = threadCount; + this.qpsLimit = qpsLimit; + this.startTime = System.currentTimeMillis(); + } + + /** + * 记录成功交易 + */ + public void recordSuccess(long latency) { + totalTransactions.incrementAndGet(); + successTransactions.incrementAndGet(); + latencies.add(latency); + totalLatency.addAndGet(latency); + } + + /** + * 记录失败交易 + */ + public void recordFailure(String errorMsg) { + totalTransactions.incrementAndGet(); + failedTransactions.incrementAndGet(); + if (errors.size() < 100) { // 只保存前100条错误 + errors.add(errorMsg); + } + } + + /** + * 标记测试结束 + */ + public void markEnd() { + this.endTime = System.currentTimeMillis(); + } + + /** + * 计算TPS + */ + public double calculateTPS() { + if (endTime == 0) { + endTime = System.currentTimeMillis(); + } + double duration = (endTime - startTime) / 1000.0; + return duration > 0 ? successTransactions.get() / duration : 0; + } + + /** + * 计算实时TPS + */ + public double getRealtimeTPS() { + long currentTime = System.currentTimeMillis(); + double duration = (currentTime - startTime) / 1000.0; + return duration > 0 ? successTransactions.get() / duration : 0; + } + + /** + * 计算成功率 + */ + public double calculateSuccessRate() { + int total = totalTransactions.get(); + return total > 0 ? (successTransactions.get() * 100.0 / total) : 0; + } + + /** + * 计算平均延迟 + */ + public double calculateAverageLatency() { + int count = successTransactions.get(); + return count > 0 ? totalLatency.get() / (double)count : 0; + } + + /** + * 计算百分位延迟 + */ + public long calculatePercentileLatency(int percentile) { + if (latencies.isEmpty()) { + return 0; + } + + List sortedLatencies = new ArrayList<>(latencies); + Collections.sort(sortedLatencies); + + int index = (int)Math.ceil(sortedLatencies.size() * percentile / 100.0) - 1; + index = Math.max(0, Math.min(index, sortedLatencies.size() - 1)); + + return sortedLatencies.get(index); + } + + /** + * 获取总交易数 + */ + public int getTotalTransactions() { + return totalTransactions.get(); + } + + /** + * 生成测试报告 + */ + public String generateReport() { + StringBuilder report = new StringBuilder(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + double duration = (endTime - startTime) / 1000.0; + double tps = calculateTPS(); + double successRate = calculateSuccessRate(); + double avgLatency = calculateAverageLatency(); + + report.append("========================================\n"); + report.append(" FISCO BCOS TPS测试报告\n"); + report.append("========================================\n\n"); + + report.append("测试配置:\n"); + report.append(" 开始时间: ").append(sdf.format(new Date(startTime))).append("\n"); + report.append(" 结束时间: ").append(sdf.format(new Date(endTime))).append("\n"); + report.append(" 测试时长: ").append(String.format("%.2f", duration)).append(" 秒\n"); + report.append(" 并发线程数: ").append(threadCount).append("\n"); + report.append(" QPS限制: ").append(qpsLimit > 0 ? qpsLimit : "无限制").append("\n"); + report.append("\n"); + + report.append("交易统计:\n"); + report.append(" 总交易数: ").append(totalTransactions.get()).append("\n"); + report.append(" 成功交易: ").append(successTransactions.get()).append("\n"); + report.append(" 失败交易: ").append(failedTransactions.get()).append("\n"); + report.append(" 成功率: ").append(String.format("%.2f%%", successRate)).append("\n"); + report.append("\n"); + + report.append("性能指标:\n"); + report.append(" ★ TPS (每秒交易数): ").append(String.format("%.2f", tps)).append("\n"); + report.append(" 平均延迟: ").append(String.format("%.2f", avgLatency)).append(" ms\n"); + + if (!latencies.isEmpty()) { + report.append(" 中位数延迟: ").append(calculatePercentileLatency(50)).append(" ms\n"); + report.append(" P95延迟: ").append(calculatePercentileLatency(95)).append(" ms\n"); + report.append(" P99延迟: ").append(calculatePercentileLatency(99)).append(" ms\n"); + } + + report.append("\n"); + report.append("报告时间: ").append(sdf.format(new Date())).append("\n"); + report.append("========================================\n"); + + // 如果有错误,显示前10条 + if (!errors.isEmpty()) { + report.append("\n错误示例 (前10条):\n"); + int count = Math.min(10, errors.size()); + for (int i = 0; i < count; i++) { + report.append(" ").append(i + 1).append(". ").append(errors.get(i)).append("\n"); + } + } + + return report.toString(); + } +} + diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..67d15fd --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tps/tps_test_report_1770703533286.txt b/tps/tps_test_report_1770703533286.txt new file mode 100644 index 0000000..2f2b29e --- /dev/null +++ b/tps/tps_test_report_1770703533286.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:04:09 + 结束时间: 2026-02-10 14:05:33 + 测试时长: 83.62 秒 + 并发线程数: 100 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 119.59 + 平均延迟: 827.52 ms + 中位数延迟: 651 ms + P95延迟: 1503 ms + P99延迟: 4310 ms + +报告时间: 2026-02-10 14:05:33 +======================================== diff --git a/tps/tps_test_report_1770703614878.txt b/tps/tps_test_report_1770703614878.txt new file mode 100644 index 0000000..0a96e34 --- /dev/null +++ b/tps/tps_test_report_1770703614878.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:06:06 + 结束时间: 2026-02-10 14:06:54 + 测试时长: 48.66 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 205.51 + 平均延迟: 1553.64 ms + 中位数延迟: 940 ms + P95延迟: 3028 ms + P99延迟: 16673 ms + +报告时间: 2026-02-10 14:06:54 +======================================== diff --git a/tps/tps_test_report_1770703670003.txt b/tps/tps_test_report_1770703670003.txt new file mode 100644 index 0000000..59ca46f --- /dev/null +++ b/tps/tps_test_report_1770703670003.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:07:12 + 结束时间: 2026-02-10 14:07:49 + 测试时长: 37.26 秒 + 并发线程数: 1000 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9611 + 失败交易: 389 + 成功率: 96.11% + +性能指标: + ★ TPS (每秒交易数): 257.98 + 平均延迟: 2229.50 ms + 中位数延迟: 1436 ms + P95延迟: 5189 ms + P99延迟: 24093 ms + +报告时间: 2026-02-10 14:07:50 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770703725649.txt b/tps/tps_test_report_1770703725649.txt new file mode 100644 index 0000000..7d1d735 --- /dev/null +++ b/tps/tps_test_report_1770703725649.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:08:12 + 结束时间: 2026-02-10 14:08:45 + 测试时长: 33.02 秒 + 并发线程数: 600 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9963 + 失败交易: 37 + 成功率: 99.63% + +性能指标: + ★ TPS (每秒交易数): 301.69 + 平均延迟: 1378.41 ms + 中位数延迟: 838 ms + P95延迟: 2297 ms + P99延迟: 21355 ms + +报告时间: 2026-02-10 14:08:45 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770703784697.txt b/tps/tps_test_report_1770703784697.txt new file mode 100644 index 0000000..132b344 --- /dev/null +++ b/tps/tps_test_report_1770703784697.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:09:10 + 结束时间: 2026-02-10 14:09:44 + 测试时长: 33.79 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9974 + 失败交易: 26 + 成功率: 99.74% + +性能指标: + ★ TPS (每秒交易数): 295.14 + 平均延迟: 1494.69 ms + 中位数延迟: 823 ms + P95延迟: 2672 ms + P99延迟: 20214 ms + +报告时间: 2026-02-10 14:09:44 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770703851041.txt b/tps/tps_test_report_1770703851041.txt new file mode 100644 index 0000000..a10e7a5 --- /dev/null +++ b/tps/tps_test_report_1770703851041.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:09:59 + 结束时间: 2026-02-10 14:10:51 + 测试时长: 51.05 秒 + 并发线程数: 400 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 195.90 + 平均延迟: 1424.86 ms + 中位数延迟: 765 ms + P95延迟: 1565 ms + P99延迟: 19399 ms + +报告时间: 2026-02-10 14:10:51 +======================================== diff --git a/tps/tps_test_report_1770703907344.txt b/tps/tps_test_report_1770703907344.txt new file mode 100644 index 0000000..0754315 --- /dev/null +++ b/tps/tps_test_report_1770703907344.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:11:09 + 结束时间: 2026-02-10 14:11:47 + 测试时长: 37.77 秒 + 并发线程数: 450 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 264.80 + 平均延迟: 1437.83 ms + 中位数延迟: 748 ms + P95延迟: 4032 ms + P99延迟: 14454 ms + +报告时间: 2026-02-10 14:11:47 +======================================== diff --git a/tps/tps_test_report_1770703956143.txt b/tps/tps_test_report_1770703956143.txt new file mode 100644 index 0000000..e149b87 --- /dev/null +++ b/tps/tps_test_report_1770703956143.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:12:06 + 结束时间: 2026-02-10 14:12:36 + 测试时长: 29.63 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 337.52 + 平均延迟: 1453.46 ms + 中位数延迟: 963 ms + P95延迟: 1863 ms + P99延迟: 20871 ms + +报告时间: 2026-02-10 14:12:36 +======================================== diff --git a/tps/tps_test_report_1770703997870.txt b/tps/tps_test_report_1770703997870.txt new file mode 100644 index 0000000..024b6b2 --- /dev/null +++ b/tps/tps_test_report_1770703997870.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:12:45 + 结束时间: 2026-02-10 14:13:17 + 测试时长: 32.47 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9973 + 失败交易: 27 + 成功率: 99.73% + +性能指标: + ★ TPS (每秒交易数): 307.19 + 平均延迟: 1366.54 ms + 中位数延迟: 739 ms + P95延迟: 2044 ms + P99延迟: 19454 ms + +报告时间: 2026-02-10 14:13:17 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770704037174.txt b/tps/tps_test_report_1770704037174.txt new file mode 100644 index 0000000..90f958e --- /dev/null +++ b/tps/tps_test_report_1770704037174.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:13:30 + 结束时间: 2026-02-10 14:13:57 + 测试时长: 26.30 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 380.26 + 平均延迟: 1285.29 ms + 中位数延迟: 881 ms + P95延迟: 2683 ms + P99延迟: 15799 ms + +报告时间: 2026-02-10 14:13:57 +======================================== diff --git a/tps/tps_test_report_1770704089881.txt b/tps/tps_test_report_1770704089881.txt new file mode 100644 index 0000000..43ed924 --- /dev/null +++ b/tps/tps_test_report_1770704089881.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:14:17 + 结束时间: 2026-02-10 14:14:49 + 测试时长: 32.00 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9948 + 失败交易: 52 + 成功率: 99.48% + +性能指标: + ★ TPS (每秒交易数): 310.87 + 平均延迟: 1362.70 ms + 中位数延迟: 870 ms + P95延迟: 1553 ms + P99延迟: 21603 ms + +报告时间: 2026-02-10 14:14:49 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770704145861.txt b/tps/tps_test_report_1770704145861.txt new file mode 100644 index 0000000..a159345 --- /dev/null +++ b/tps/tps_test_report_1770704145861.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:15:18 + 结束时间: 2026-02-10 14:15:45 + 测试时长: 27.54 秒 + 并发线程数: 450 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 363.17 + 平均延迟: 1137.05 ms + 中位数延迟: 755 ms + P95延迟: 1664 ms + P99延迟: 13455 ms + +报告时间: 2026-02-10 14:15:45 +======================================== diff --git a/tps/tps_test_report_1770704200012.txt b/tps/tps_test_report_1770704200012.txt new file mode 100644 index 0000000..3363203 --- /dev/null +++ b/tps/tps_test_report_1770704200012.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:15:55 + 结束时间: 2026-02-10 14:16:39 + 测试时长: 44.96 秒 + 并发线程数: 450 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 222.42 + 平均延迟: 1618.69 ms + 中位数延迟: 817 ms + P95延迟: 6077 ms + P99延迟: 20877 ms + +报告时间: 2026-02-10 14:16:40 +======================================== diff --git a/tps/tps_test_report_1770704258358.txt b/tps/tps_test_report_1770704258358.txt new file mode 100644 index 0000000..6006125 --- /dev/null +++ b/tps/tps_test_report_1770704258358.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:16:51 + 结束时间: 2026-02-10 14:17:38 + 测试时长: 47.00 秒 + 并发线程数: 450 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 212.76 + 平均延迟: 1825.84 ms + 中位数延迟: 885 ms + P95延迟: 5084 ms + P99延迟: 16504 ms + +报告时间: 2026-02-10 14:17:38 +======================================== diff --git a/tps/tps_test_report_1770704309502.txt b/tps/tps_test_report_1770704309502.txt new file mode 100644 index 0000000..c3527b2 --- /dev/null +++ b/tps/tps_test_report_1770704309502.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:17:49 + 结束时间: 2026-02-10 14:18:29 + 测试时长: 40.11 秒 + 并发线程数: 450 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 249.33 + 平均延迟: 1341.90 ms + 中位数延迟: 738 ms + P95延迟: 3098 ms + P99延迟: 12218 ms + +报告时间: 2026-02-10 14:18:29 +======================================== diff --git a/tps/tps_test_report_1770704940931.txt b/tps/tps_test_report_1770704940931.txt new file mode 100644 index 0000000..abb7fb4 --- /dev/null +++ b/tps/tps_test_report_1770704940931.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:23:37 + 结束时间: 2026-02-10 14:29:00 + 测试时长: 323.22 秒 + 并发线程数: 400 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 309.38 + 平均延迟: 1289.31 ms + 中位数延迟: 782 ms + P95延迟: 2880 ms + P99延迟: 13821 ms + +报告时间: 2026-02-10 14:29:00 +======================================== diff --git a/tps/tps_test_report_1770705295952.txt b/tps/tps_test_report_1770705295952.txt new file mode 100644 index 0000000..77b98a4 --- /dev/null +++ b/tps/tps_test_report_1770705295952.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:29:13 + 结束时间: 2026-02-10 14:34:55 + 测试时长: 342.83 秒 + 并发线程数: 400 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 291.69 + 平均延迟: 1336.06 ms + 中位数延迟: 772 ms + P95延迟: 4855 ms + P99延迟: 11606 ms + +报告时间: 2026-02-10 14:34:56 +======================================== diff --git a/tps/tps_test_report_1770705629081.txt b/tps/tps_test_report_1770705629081.txt new file mode 100644 index 0000000..d5340d2 --- /dev/null +++ b/tps/tps_test_report_1770705629081.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:35:06 + 结束时间: 2026-02-10 14:40:29 + 测试时长: 322.86 秒 + 并发线程数: 400 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 309.73 + 平均延迟: 1272.72 ms + 中位数延迟: 767 ms + P95延迟: 2771 ms + P99延迟: 12284 ms + +报告时间: 2026-02-10 14:40:29 +======================================== diff --git a/tps/tps_test_report_1770705915424.txt b/tps/tps_test_report_1770705915424.txt new file mode 100644 index 0000000..2ad52ef --- /dev/null +++ b/tps/tps_test_report_1770705915424.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:41:15 + 结束时间: 2026-02-10 14:45:15 + 测试时长: 240.15 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 416.41 + 平均延迟: 1170.71 ms + 中位数延迟: 772 ms + P95延迟: 1779 ms + P99延迟: 12080 ms + +报告时间: 2026-02-10 14:45:15 +======================================== diff --git a/tps/tps_test_report_1770706188440.txt b/tps/tps_test_report_1770706188440.txt new file mode 100644 index 0000000..0e8da46 --- /dev/null +++ b/tps/tps_test_report_1770706188440.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:45:27 + 结束时间: 2026-02-10 14:49:48 + 测试时长: 260.41 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 384.01 + 平均延迟: 1241.56 ms + 中位数延迟: 757 ms + P95延迟: 2237 ms + P99延迟: 13599 ms + +报告时间: 2026-02-10 14:49:48 +======================================== diff --git a/tps/tps_test_report_1770706244570.txt b/tps/tps_test_report_1770706244570.txt new file mode 100644 index 0000000..e371055 --- /dev/null +++ b/tps/tps_test_report_1770706244570.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:49:59 + 结束时间: 2026-02-10 14:50:44 + 测试时长: 45.36 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 220.48 + 平均延迟: 1668.52 ms + 中位数延迟: 829 ms + P95延迟: 3114 ms + P99延迟: 17204 ms + +报告时间: 2026-02-10 14:50:44 +======================================== diff --git a/tps/tps_test_report_1770706296093.txt b/tps/tps_test_report_1770706296093.txt new file mode 100644 index 0000000..372ebfd --- /dev/null +++ b/tps/tps_test_report_1770706296093.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:50:54 + 结束时间: 2026-02-10 14:51:36 + 测试时长: 41.70 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 239.84 + 平均延迟: 1534.05 ms + 中位数延迟: 806 ms + P95延迟: 4673 ms + P99延迟: 15583 ms + +报告时间: 2026-02-10 14:51:36 +======================================== diff --git a/tps/tps_test_report_1770706337416.txt b/tps/tps_test_report_1770706337416.txt new file mode 100644 index 0000000..9da635e --- /dev/null +++ b/tps/tps_test_report_1770706337416.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:51:52 + 结束时间: 2026-02-10 14:52:17 + 测试时长: 24.52 秒 + 并发线程数: 600 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 407.90 + 平均延迟: 1313.38 ms + 中位数延迟: 805 ms + P95延迟: 2667 ms + P99延迟: 16736 ms + +报告时间: 2026-02-10 14:52:17 +======================================== diff --git a/tps/tps_test_report_1770706383079.txt b/tps/tps_test_report_1770706383079.txt new file mode 100644 index 0000000..f9b2b22 --- /dev/null +++ b/tps/tps_test_report_1770706383079.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:52:37 + 结束时间: 2026-02-10 14:53:03 + 测试时长: 25.28 秒 + 并发线程数: 600 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 395.65 + 平均延迟: 1393.95 ms + 中位数延迟: 884 ms + P95延迟: 2074 ms + P99延迟: 17573 ms + +报告时间: 2026-02-10 14:53:03 +======================================== diff --git a/tps/tps_test_report_1770706440306.txt b/tps/tps_test_report_1770706440306.txt new file mode 100644 index 0000000..8b8bb2a --- /dev/null +++ b/tps/tps_test_report_1770706440306.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:53:19 + 结束时间: 2026-02-10 14:54:00 + 测试时长: 40.41 秒 + 并发线程数: 1000 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9396 + 失败交易: 604 + 成功率: 93.96% + +性能指标: + ★ TPS (每秒交易数): 232.53 + 平均延迟: 1836.32 ms + 中位数延迟: 869 ms + P95延迟: 7908 ms + P99延迟: 22325 ms + +报告时间: 2026-02-10 14:54:00 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770706497453.txt b/tps/tps_test_report_1770706497453.txt new file mode 100644 index 0000000..e27cd35 --- /dev/null +++ b/tps/tps_test_report_1770706497453.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:54:24 + 结束时间: 2026-02-10 14:54:57 + 测试时长: 32.47 秒 + 并发线程数: 800 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 9988 + 失败交易: 12 + 成功率: 99.88% + +性能指标: + ★ TPS (每秒交易数): 307.64 + 平均延迟: 1746.19 ms + 中位数延迟: 916 ms + P95延迟: 3013 ms + P99延迟: 25522 ms + +报告时间: 2026-02-10 14:54:57 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770706529950.txt b/tps/tps_test_report_1770706529950.txt new file mode 100644 index 0000000..186268c --- /dev/null +++ b/tps/tps_test_report_1770706529950.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:55:09 + 结束时间: 2026-02-10 14:55:29 + 测试时长: 20.70 秒 + 并发线程数: 600 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 483.14 + 平均延迟: 1142.64 ms + 中位数延迟: 775 ms + P95延迟: 1565 ms + P99延迟: 12320 ms + +报告时间: 2026-02-10 14:55:29 +======================================== diff --git a/tps/tps_test_report_1770706574616.txt b/tps/tps_test_report_1770706574616.txt new file mode 100644 index 0000000..0e73606 --- /dev/null +++ b/tps/tps_test_report_1770706574616.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:55:47 + 结束时间: 2026-02-10 14:56:14 + 测试时长: 27.47 秒 + 并发线程数: 600 + QPS限制: 无限制 + +交易统计: + 总交易数: 10000 + 成功交易: 10000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 364.07 + 平均延迟: 1467.61 ms + 中位数延迟: 809 ms + P95延迟: 2798 ms + P99延迟: 22015 ms + +报告时间: 2026-02-10 14:56:14 +======================================== diff --git a/tps/tps_test_report_1770706999829.txt b/tps/tps_test_report_1770706999829.txt new file mode 100644 index 0000000..503bd12 --- /dev/null +++ b/tps/tps_test_report_1770706999829.txt @@ -0,0 +1,38 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 14:58:44 + 结束时间: 2026-02-10 15:03:19 + 测试时长: 275.23 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 99822 + 失败交易: 178 + 成功率: 99.82% + +性能指标: + ★ TPS (每秒交易数): 362.68 + 平均延迟: 1299.76 ms + 中位数延迟: 807 ms + P95延迟: 2194 ms + P99延迟: 14605 ms + +报告时间: 2026-02-10 15:03:19 +======================================== + +错误示例 (前10条): + 1. 交易执行失败 + 2. 交易执行失败 + 3. 交易执行失败 + 4. 交易执行失败 + 5. 交易执行失败 + 6. 交易执行失败 + 7. 交易执行失败 + 8. 交易执行失败 + 9. 交易执行失败 + 10. 交易执行失败 diff --git a/tps/tps_test_report_1770707384682.txt b/tps/tps_test_report_1770707384682.txt new file mode 100644 index 0000000..14765f2 --- /dev/null +++ b/tps/tps_test_report_1770707384682.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 15:04:54 + 结束时间: 2026-02-10 15:09:44 + 测试时长: 290.01 秒 + 并发线程数: 400 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 344.81 + 平均延迟: 1146.03 ms + 中位数延迟: 755 ms + P95延迟: 1997 ms + P99延迟: 10785 ms + +报告时间: 2026-02-10 15:09:44 +======================================== diff --git a/tps/tps_test_report_1770707638802.txt b/tps/tps_test_report_1770707638802.txt new file mode 100644 index 0000000..a82d0f5 --- /dev/null +++ b/tps/tps_test_report_1770707638802.txt @@ -0,0 +1,26 @@ +======================================== + FISCO BCOS TPS测试报告 +======================================== + +测试配置: + 开始时间: 2026-02-10 15:09:55 + 结束时间: 2026-02-10 15:13:58 + 测试时长: 243.54 秒 + 并发线程数: 500 + QPS限制: 无限制 + +交易统计: + 总交易数: 100000 + 成功交易: 100000 + 失败交易: 0 + 成功率: 100.00% + +性能指标: + ★ TPS (每秒交易数): 410.61 + 平均延迟: 1198.27 ms + 中位数延迟: 780 ms + P95延迟: 2089 ms + P99延迟: 10839 ms + +报告时间: 2026-02-10 15:13:58 +========================================