4、加解密性能评估:不同算法的QPS、延迟、CPU开销测试
性能评估这事儿,说白了就是拿数据说话。我见过不少团队选加密算法只凭“感觉”:AES快,RSA慢,但对业务到底有多大影响,没人说清楚。你想想看,做一个存量字段加密迁移,如果选错了算法,线上QPS直接腰斩,那可不是闹着玩的。
我个人习惯,在做任何加密方案前,先跑一轮性能压测。这章我就把压测的方法、常用算法的表现,以及我踩过的坑都摊开来讲。
测试环境与工具
先交代一下硬件基线。我用的是一台4核8G的云服务器(Intel Xeon Platinum 8269CY),操作系统CentOS 7.9。压力工具用的是wrk + 自研的JMeter插件,监控资源用perf和top。
| 项目 | 配置 |
|---|---|
| CPU | 4 vCPU (2.5 GHz) |
| 内存 | 8 GB |
| 测试负载 | 100 并发连接,持续 120 秒 |
| 密钥长度 | AES-256 / SM4-128 / RSA-2048 / ECC-256 |
一点经验:压测最好独占机器,避免其他进程干扰。我有一回忘了关crontab,结果CPU曲线飘得没法看。
测试方法
我按照“吞吐优先,兼顾延迟”的思路,设计了两个场景:
- 纯加密/解密:固定1KB数据,循环执行,记录QPS和P99延迟。
- 混合负载:模拟业务读写(70%读、30%写),记录CPU占用率和系统平均负载。
下面是核心压测代码片段(Java + OpenSSL),方便你复现:
// AES-256 加密测试示例
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] plaintext = new byte[1024];
long start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
cipher.doFinal(plaintext);
}
long elapsed = System.nanoTime() - start;
System.out.println("QPS: " + (10000 * 1_000_000_000L / elapsed));
注意:每次加密前要重新初始化IV,否则GCM模式下性能会因IV复用而下降。我曾经忘记重置cipher对象,测试结果偏差了30%以上。
测试结果:主流算法对比
下面是我跑出来的典型数据(取5次平均,去掉最高最低):
| 算法 | 加密QPS | 解密QPS | P99延迟(ms) | CPU开销(%) |
|---|---|---|---|---|
| AES-256-GCM | 58,200 | 57,900 | 0.12 | 62% |
| SM4-GCM | 42,100 | 41,600 | 0.18 | 78% |
| RSA-2048 (私钥解密) | 2,800 | 19,400 | 2.10 | 91% |
| ECC-256 (私钥签名) | 9,600 | 18,200 | 0.85 | 83% |
看到没?对称加密和非对称的差距是数量级的。AES的QPS接近6万,而RSA连3000都不到。日常业务中,如果要对每条请求做RSA解密,CPU瞬间就满了。
关键结论:对称加密适合大量数据字段的实时加密,非对称只能用于密钥协商或少量签名场景。
性能评估流程图
我把整个评估思路画成了一张图,方便大家对照实施:
算法选型建议
根据上面的测试结果,结合字段加密场景,我给几个实际建议:
- 对称加密首选 AES-256-GCM:性能优秀,且自带认证加密。SM4也不错,但国内合规场景才必须用。
- 非对称只用做密钥交换:千万别直接加密字段。我见过一个项目用RSA加密手机号,上线第一天CPU就报警了。
- ECC比RSA快3倍以上:同等安全强度下,ECC-256的签名速度远高于RSA-2048。做数字签名时优先考虑ECC。
降本小技巧:如果业务敏感字段很少变更(比如身份证号),可以提前加密好存到数据库,查询时只做解密 — 这样解密QPS就是硬上限,不会和写冲突。
常见坑与避让
最后聊几个我在性能评估中踩过的坑:
- 忘记预热JIT:Java的JIT对加密循环影响很大。我有一回没预热,结果前10秒QPS只有3000,预热后直接冲到5万。一定要先跑够warm-up时间。
- GCM模式性能陷阱:AES-GCM在Intel芯片上有AES-NI指令加速,但SM4目前没有硬件加速。如果SM4用作高性能场景,要评估CPU压力。
- 混用线程池:曾经有人把加密操作丢进公共业务线程池,结果业务延迟飙升。我建议单独设置加密专用的线程池,隔离资源。
- 忽略序列化开销:加密前要把对象转成字节数组,这个序列化过程也可能吃掉大量CPU。压测时要一并计入。
紧急提醒:生产环境做性能评估时,务必在预发环境先跑,并做好降级预案。有一次我在压测时触发了连接池打满,差点导致线上故障——回想起来都后怕。
嗯,关于性能评估的核心内容就这些。拿到这些数据,你就能在双写或迁移方案中,底气十足地告诉老板:“选AES,没问题。” 至于怎么把字段加密无缝嵌入业务,我们后面会细讲。