From b82002801d2fc268dca2054cde7f252e0219fb37 Mon Sep 17 00:00:00 2001 From: cheney Date: Mon, 8 Jun 2026 17:03:46 +0800 Subject: [PATCH] =?UTF-8?q?jmeter=20=E6=B5=8B=E8=AF=95=E5=8F=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jmeter/招行测试计划.jmx | 553 +++++++++++++++++- .../java/com/sunyard/entity/TimeStats.java | 103 ++++ .../java/racal/sunyard/main/SydApi4j.java | 144 +++++ src/test/java/cmbpoc/PerformanceTest.java | 45 ++ 4 files changed, 838 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/sunyard/entity/TimeStats.java diff --git a/jmeter/招行测试计划.jmx b/jmeter/招行测试计划.jmx index 0a261aa..2a5b3ff 100644 --- a/jmeter/招行测试计划.jmx +++ b/jmeter/招行测试计划.jmx @@ -9,6 +9,7 @@ + @@ -243,7 +244,7 @@ - + continue false @@ -475,11 +476,11 @@ - + continue false - 10 + 10000 1 1 @@ -542,7 +543,7 @@ cmbpoc.JmeterTest - + false saveConfig @@ -579,7 +580,7 @@ - + false saveConfig @@ -653,7 +654,7 @@ - + false saveConfig @@ -698,7 +699,545 @@ false - + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + 1000 + false + + + + + false + false + + + + + continue + + false + 100 + + 1 + 1 + false + + + true + + + + + + + function + SYD_SM2_Encrypt + = + + + sleep + 1 + = + + + plainDataLen + 2097152 + = + + + publicKey4Ende + 03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7 + = + + + privateKey4Ende + 00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000 + = + + + ip + 192.168.100.145 + = + + + ip2 + 172.1.41.96 + = + + + port + 8889 + = + + + timeout + 3000 + = + + + + cmbpoc.JmeterTest + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + 500 + false + + + + + false + false + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + 1000 + false + + + + + false + false + + + + + continue + + false + 100 + + 1 + 1 + false + + + true + + + + + + + function + SYD_SM2_Encrypt + = + + + sleep + 1 + = + + + plainDataLen + 2048 + = + + + publicKey4Ende + 03420004AF3D4E55D26564C6C937E6EA9232691C01AC5E7916AD2136F788CE7C1E4D0AE8C4754DEC2F7F6A78962D51A171A6F5B4F11823390AEC8B5B0246CD2CCF8052B7 + = + + + privateKey4Ende + 00010000963F7C3A98B7810F52D2861A060E18A9D4D59796CF33967DD61EEDA091E1AD9B0000000000000000000000000000000000000000000000000000000000000000 + = + + + ip + 192.168.100.145 + = + + + ip2 + 172.1.41.96 + = + + + port + 8889 + = + + + timeout + 3000 + = + + + + cmbpoc.JmeterTest + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + + + + false + + saveConfig + + + true + true + true + + true + true + true + true + false + true + true + false + false + false + true + false + false + false + true + 0 + true + true + true + true + true + true + + + + 500 + false + + + + + false + false + + + false saveConfig diff --git a/src/main/java/com/sunyard/entity/TimeStats.java b/src/main/java/com/sunyard/entity/TimeStats.java new file mode 100644 index 0000000..ce53ed1 --- /dev/null +++ b/src/main/java/com/sunyard/entity/TimeStats.java @@ -0,0 +1,103 @@ +package com.sunyard.entity; + +/** + * SM2加密解密时间统计类 + * 用于记录发送、计算、接收三个阶段的耗时 + */ +public class TimeStats { + // 发送阶段总耗时(毫秒)- 循环发送数据块的时间 + private long sendTime; + // 计算阶段耗时(毫秒)- 执行加密/解密计算的时间 + private long computeTime; + // 接收阶段总耗时(毫秒)- 循环接收数据块的时间 + private long receiveTime; + // 发送次数 + private int sendCount; + // 接收次数 + private int receiveCount; + + public TimeStats() { + this.sendTime = 0; + this.computeTime = 0; + this.receiveTime = 0; + this.sendCount = 0; + this.receiveCount = 0; + } + + public long getSendTime() { + return sendTime; + } + + public void setSendTime(long sendTime) { + this.sendTime = sendTime; + } + + public long getComputeTime() { + return computeTime; + } + + public void setComputeTime(long computeTime) { + this.computeTime = computeTime; + } + + public long getReceiveTime() { + return receiveTime; + } + + public void setReceiveTime(long receiveTime) { + this.receiveTime = receiveTime; + } + + public int getSendCount() { + return sendCount; + } + + public void setSendCount(int sendCount) { + this.sendCount = sendCount; + } + + public int getReceiveCount() { + return receiveCount; + } + + public void setReceiveCount(int receiveCount) { + this.receiveCount = receiveCount; + } + + /** + * 获取总耗时 + */ + public long getTotalTime() { + return sendTime + computeTime + receiveTime; + } + + /** + * 获取各阶段耗时占比 + */ + public double getSendPercentage() { + long total = getTotalTime(); + return total == 0 ? 0 : (double) sendTime / total * 100; + } + + public double getComputePercentage() { + long total = getTotalTime(); + return total == 0 ? 0 : (double) computeTime / total * 100; + } + + public double getReceivePercentage() { + long total = getTotalTime(); + return total == 0 ? 0 : (double) receiveTime / total * 100; + } + + @Override + public String toString() { + return String.format( + "TimeStats{sendTime=%dms(%.1f%%), computeTime=%dms(%.1f%%), receiveTime=%dms(%.1f%%), total=%dms, sendCount=%d, receiveCount=%d}", + sendTime, getSendPercentage(), + computeTime, getComputePercentage(), + receiveTime, getReceivePercentage(), + getTotalTime(), + sendCount, receiveCount + ); + } +} diff --git a/src/main/java/racal/sunyard/main/SydApi4j.java b/src/main/java/racal/sunyard/main/SydApi4j.java index 6ba343f..7cc4334 100644 --- a/src/main/java/racal/sunyard/main/SydApi4j.java +++ b/src/main/java/racal/sunyard/main/SydApi4j.java @@ -16,6 +16,7 @@ import com.sunyard.constant.CertUsage; import com.sunyard.entity.ImportResult; import com.sunyard.entity.MutiReturn7; import com.sunyard.entity.Struct; +import com.sunyard.entity.TimeStats; import com.sunyard.log.ILogFactory; import com.sunyard.log.ILogger; import com.sunyard.proto.Packet; @@ -7170,6 +7171,149 @@ public class SydApi4j implements SydApi { } } + /** + * SM2 加密(支持大包分段)- 带时间统计 + * @param publicKey 公钥字节数组 + * @param pOrgData 明文数据 + * @param timeStats 时间统计对象(输出参数) + * @return 加密后的密文 + */ + public byte[] SYD_SM2Encrypt(byte[] publicKey, byte[] pOrgData, TimeStats timeStats){ + ParamChecker.checkNotNull(publicKey, "publicKey"); + ParamChecker.checkNotNull(pOrgData, "pOrgData"); + + final int CHUNK_SIZE = 62 * 1024; // 62 KB + int dataLen = pOrgData.length; + int offset = 0; + long sendStartTime = System.currentTimeMillis(); + int sendCount = 0; + + while (offset < dataLen) { + int len = Math.min(CHUNK_SIZE, dataLen - offset); + SYD_SM2Encrypt(1, publicKey, ByteBuffer.wrap(pOrgData, offset, len), offset, len, dataLen); + offset += len; + sendCount++; + } + long sendEndTime = System.currentTimeMillis(); + + long computeStartTime = System.currentTimeMillis(); + SYD_SM2Encrypt(2, publicKey, null, 0, 0, dataLen); + long computeEndTime = System.currentTimeMillis(); + + long receiveStartTime = System.currentTimeMillis(); + int idx = 0; + List chunks = new ArrayList<>(); + int totalLen = 0; + int isLast = 0; + int receiveCount = 0; + + while (isLast != 1) { + MutiReturn7 ret = SYD_SM2Encrypt(3, null, null, idx, 0, 0); + ByteBuffer bb = ret.getData(); + isLast = ret.getIsLast(); + + if (bb != null && bb.remaining() > 0) { + int remaining = bb.remaining(); + chunks.add(bb); + totalLen += remaining; + idx += remaining; + receiveCount++; + } else if (isLast != 1) { + throw new RuntimeException("Empty chunk with isLast=0"); + } + } + long receiveEndTime = System.currentTimeMillis(); + + byte[] result = new byte[totalLen]; + int offset2 = 0; + for (ByteBuffer chunk : chunks) { + int len = chunk.remaining(); + chunk.get(result, offset2, len); + offset2 += len; + } + + if (timeStats != null) { + timeStats.setSendTime(sendEndTime - sendStartTime); + timeStats.setComputeTime(computeEndTime - computeStartTime); + timeStats.setReceiveTime(receiveEndTime - receiveStartTime); + timeStats.setSendCount(sendCount); + timeStats.setReceiveCount(receiveCount); + } + + return result; + } + + /** + * SM2 解密(支持大包分段)- 带时间统计 + * @param privateKey 私钥字节数组 + * @param pCipherData 密文数据 + * @param timeStats 时间统计对象(输出参数) + * @return 解密后的明文 + */ + public byte[] SYD_SM2Decrypt(byte[] privateKey, byte[] pCipherData, TimeStats timeStats) { + ParamChecker.checkNotNull(privateKey, "privateKey"); + ParamChecker.checkNotNull(pCipherData, "pCipherData"); + + final int CHUNK_SIZE = 62 * 1024; // 62 KB,与加密保持一致 + int dataLen = pCipherData.length; + int offset = 0; + long sendStartTime = System.currentTimeMillis(); + int sendCount = 0; + + while (offset < dataLen) { + int len = Math.min(CHUNK_SIZE, dataLen - offset); + SYD_SM2Decrypt(1, privateKey, ByteBuffer.wrap(pCipherData, offset, len), offset, len, 0); + offset += len; + sendCount++; + } + long sendEndTime = System.currentTimeMillis(); + + long computeStartTime = System.currentTimeMillis(); + SYD_SM2Decrypt(2, privateKey, null, 0, 0, dataLen); + long computeEndTime = System.currentTimeMillis(); + + long receiveStartTime = System.currentTimeMillis(); + int idx = 0; + List chunks = new ArrayList<>(); + int totalLen = 0; + int isLast = 0; + int receiveCount = 0; + + while (isLast != 1) { + MutiReturn7 ret = SYD_SM2Decrypt(3, null, null, idx, 0, 0); + ByteBuffer bb = ret.getData(); + isLast = ret.getIsLast(); + + if (bb != null && bb.remaining() > 0) { + chunks.add(bb); + totalLen += bb.remaining(); + idx += bb.remaining(); + receiveCount++; + } else if (isLast != 1) { + throw new RuntimeException("Empty plain chunk with isLast=0"); + } + } + long receiveEndTime = System.currentTimeMillis(); + + byte[] result = new byte[totalLen]; + int offset2 = 0; + for (ByteBuffer chunk : chunks) { + int len = chunk.remaining(); + chunk.get(result, offset2, len); + offset2 += len; + } + + if (timeStats != null) { + timeStats.setSendTime(sendEndTime - sendStartTime); + timeStats.setComputeTime(computeEndTime - computeStartTime); + timeStats.setReceiveTime(receiveEndTime - receiveStartTime); + timeStats.setSendCount(sendCount); + timeStats.setReceiveCount(receiveCount); + } + + return result; + } + @Override public String SM2Encrypt(byte[] publicKey, byte[] pOrgData) { diff --git a/src/test/java/cmbpoc/PerformanceTest.java b/src/test/java/cmbpoc/PerformanceTest.java index 435beb4..ee2eaec 100644 --- a/src/test/java/cmbpoc/PerformanceTest.java +++ b/src/test/java/cmbpoc/PerformanceTest.java @@ -2,6 +2,7 @@ package cmbpoc; import com.sunyard.RetWrap; import com.sunyard.SydApi; +import com.sunyard.entity.TimeStats; import com.sunyard.proto.Util; import org.junit.*; import racal.sunyard.main.SydApi4j; @@ -136,4 +137,48 @@ public class PerformanceTest { System.out.printf("Decrypt Throughput: %.2f KB/s%n", decryptThroughput); System.out.println(); } + + @Test + public void SYD_SM2_Encrypt_TimeStats_2M() { + System.out.println("=== SYD_SM2_Encrypt Time Statistics Test - 2M Data ==="); + + // 预热 + for (int i = 0; i < 2; i++) { + byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M); + byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData); + } + + // 正式测试 + TimeStats encryptStats = new TimeStats(); + TimeStats decryptStats = new TimeStats(); + + byte[] enData = this.api.SYD_SM2Encrypt(publicKey4Ende, orgData2M, encryptStats); + byte[] deData = this.api.SYD_SM2Decrypt(privateKey4Ende, enData, decryptStats); + + Assert.assertArrayEquals(orgData2M, deData); + + System.out.println("\n--- 加密阶段时间统计 ---"); + System.out.printf("发送阶段: %d ms (%.1f%%), 发送次数: %d%n", + encryptStats.getSendTime(), encryptStats.getSendPercentage(), encryptStats.getSendCount()); + System.out.printf("计算阶段: %d ms (%.1f%%)%n", + encryptStats.getComputeTime(), encryptStats.getComputePercentage()); + System.out.printf("接收阶段: %d ms (%.1f%%), 接收次数: %d%n", + encryptStats.getReceiveTime(), encryptStats.getReceivePercentage(), encryptStats.getReceiveCount()); + System.out.printf("加密总耗时: %d ms%n", encryptStats.getTotalTime()); + + System.out.println("\n--- 解密阶段时间统计 ---"); + System.out.printf("发送阶段: %d ms (%.1f%%), 发送次数: %d%n", + decryptStats.getSendTime(), decryptStats.getSendPercentage(), decryptStats.getSendCount()); + System.out.printf("计算阶段: %d ms (%.1f%%)%n", + decryptStats.getComputeTime(), decryptStats.getComputePercentage()); + System.out.printf("接收阶段: %d ms (%.1f%%), 接收次数: %d%n", + decryptStats.getReceiveTime(), decryptStats.getReceivePercentage(), decryptStats.getReceiveCount()); + System.out.printf("解密总耗时: %d ms%n", decryptStats.getTotalTime()); + + System.out.println("\n--- 汇总 ---"); + long totalTime = encryptStats.getTotalTime() + decryptStats.getTotalTime(); + System.out.printf("加密解密总耗时: %d ms%n", totalTime); + System.out.printf("加密吞吐量: %.2f KB/s%n", (2048.0 / encryptStats.getTotalTime()) * 1000); + System.out.printf("解密吞吐量: %.2f KB/s%n", (2048.0 / decryptStats.getTotalTime()) * 1000); + } }