3. OCSP 性能影响因素

做 OCSP 性能分析这几年,我踩过最多的坑,就是只盯着 OCSP 响应器的 CPU 和内存,却忽略了那些看不见的“隐性杀手”。

网络延迟、证书链长度、签名算法、并发量——这四个因素,任何一个没控制好,都能让 OCSP 响应时间从毫秒级飙到秒级。咱们一个一个拆开聊。

3.1 网络延迟

OCSP 本质上是个实时查询协议。客户端发起 OCSP 请求,响应器返回状态。这一来一回,网络延迟是硬成本。

我遇到过一回:某金融客户的 OCSP 平均响应时间 800ms,业务方天天投诉。我抓包一看,请求从上海到北京,RTT 本来就 30ms,但服务器端处理只用了 5ms。剩下的 765ms 哪去了?——是 DNS 解析、TCP 三次握手、TLS 握手层层叠加。

实际项目中,网络延迟对 OCSP 性能的影响,可以用这个公式估算:

T_ocsp = T_dns + T_tcp_handshake + T_tls_handshake + T_http_roundtrip + T_server_process

举个典型数值:

阶段 本地同机房 同城跨机房 跨省(1000km)
DNS 解析 0.5ms 2ms 10ms
TCP 握手 0.3ms 2ms 15ms
TLS 握手 2ms 8ms 40ms
HTTP 往返 0.2ms 1ms 10ms
服务器处理 3ms 3ms 3ms
总计 6ms 16ms 78ms

关键结论:跨省场景下,网络开销占总时间的 96%。优化网络路径比压服务器划算得多。

避坑指南:我曾经以为 OCSP Stapling 能完全绕开网络延迟,后来发现它只消除了客户端到 CA 的请求,但服务器本身去 OCSP 响应器获取 staple 的过程仍然受网络影响。如果 Stapling 获取超时,客户端会回退到直连查询——那延迟更惨。

3.2 证书链长度

OCSP 响应里得带上签发者的证书链,客户端才能验证签名。链越长,响应包越大,传输和解析都更慢。

我做过一个测试:用一张深度为 1 的叶子证书(只带根),响应体约 1.2KB;换成深度为 4 的证书链(根→二级→三级→叶子),响应体膨胀到 5.8KB。在 1Mbps 的受限网络下,传输时间从 10ms 涨到了 48ms。

而且,客户端解析多级证书链时,还得逐一校验每个中间证书的有效期、签名、吊销状态——这又平添 CPU 开销。

证书链长度 响应体大小 传输时间(1Mbps) 客户端解析时间
2 级(根+叶子) ~1.2KB ~10ms ~1ms
3 级 ~3KB ~24ms ~3ms
4 级 ~5.8KB ~48ms ~7ms
5 级 ~9KB ~72ms ~15ms

注意:证书链长度超过 4 级时,OCSP 响应很容易超过 TCP 初始拥塞窗口(通常 10 个包约 1.4KB),导致多一次 RTT。我见过一个生产案例,证书链 6 级,结果每次 OCSP 查询都要额外等一次网络往返,平白多了 30ms。

3.3 签名算法

OCSP 响应必须用数字签名保护。签名算法不同,计算耗时就差出一个数量级。

你想想看:RSA 2048 签名,在通用 CPU 上大概耗时 0.5-1ms;换成 ECDSA P-256,只要 0.1-0.2ms。但验证端更关键——我压测时发现,RSA 2048 验证耗时约 0.3ms,而 ECDSA P-256 只需要 0.05ms。别小看这几百微秒,在高并发下积少成多。

签名算法 签名耗时(服务器) 验证耗时(客户端) 密钥长度 安全强度
RSA 2048 ~0.8ms ~0.3ms 2048 bit 112 位等效
RSA 4096 ~3.5ms ~1.0ms 4096 bit 128 位等效
ECDSA P-256 ~0.15ms ~0.05ms 256 bit 128 位等效
ECDSA P-384 ~0.3ms ~0.12ms 384 bit 192 位等效
Ed25519 ~0.08ms ~0.04ms 256 bit 128 位等效

我的习惯:新项目默认用 ECDSA P-256 或 Ed25519。RSA 4096 除了兼容老旧设备几乎没有优势。有一次我把客户的 OCSP 响应器从 RSA 2048 切到 Ed25519,同机器 QPS 从 8000 涨到了 18000——不需要改代码,只换了证书。

3.4 并发量

并发数一上去,OCSP 响应器就开始“打架”。主要瓶颈有三个:连接数、签名队列、数据库查询。

  • 连接数:每个 OCSP 请求都会占用一个 TCP 连接。Linux 上默认 65535 个端口够用吗?实际上,多了会触发 TIME_WAIT 堆积,新连接建不起来。我记得有个线上事故,就是端口被占满,OCSP 响应器拒绝服务。
  • 签名队列:异步签名能扛并发,但私钥操作是计算密集型。3000 QPS 以下单线程签名还行,超过这个阈值,签名队列就开始排队。
  • 数据库查询:OCSP 响应器需要查数据库判断证书状态。没加缓存的话,每秒 1000 个查询就能让 MySQL 打嗝。

我压测时会关注这三个指标:

# 模拟 2000 并发,持续 60 秒
ab -n 120000 -c 2000 -k https://ocsp.example.com/status

# 观察指标
# 1. 平均响应时间(正常 < 20ms,临界 > 100ms)
# 2. 99 分位延迟(警惕 500ms 以上)
# 3. 失败率(> 0.1% 就开始排查)
# 4. 服务器 TIME_WAIT 连接数(ss -s | grep TIME_WAIT)
# 5. 签名队列深度(响应器内部监控)

经验之谈:我用个公式估算并发瓶颈。假设单个请求签名耗时 0.5ms,数据库查询 1ms,那么理论最大 QPS ≈ 1 / (0.5ms + 1ms) ≈ 666。实际还要打 50% 折扣,因为线程切换、锁竞争、网络都会吃掉资源。所以 300 QPS 以上就该考虑优化了。

我曾经:接手过一个 OCSP 响应器,并发上百就崩溃。查了一圈发现,数据库里没有加索引,每次查询都是全表扫描。加了联合索引之后,QPS 直接翻了 5 倍。有时候瓶颈不在你盯着的地方,多看看下游。

知识体系总览

下面这张图总结了四个影响因素的关系。你看,网络延迟和证书链长度影响的是“传输路径”,签名算法影响的是“计算路径”,并发量则把这两条路径上的所有短板都放大。定位性能瓶颈时,顺着这个结构逐一排查,不会遗漏。

OCSP 性能影响因素关系图 OCSP 性能影响因素 网络延迟 RTT / DNS / TLS 握手 证书链长度 响应体大小 / 解析开销 签名算法 RSA / ECDSA / Ed25519 并发量 连接数 / 队列 / 数据库 性能瓶颈定位路径 传输路径:网络延迟 + 证书链长度 计算路径:签名算法 放大因素:并发量 排查时从最左侧开始,依次检查,别跳步

写完这四块,其实你会发现——它们常常互相影响。比如证书链长了,响应包变大,网络传输时间增加;网络一慢,又导致 TCP 连接长时间占用,变相消耗并发能力。签名算法慢了,签名队列积压,同样的并发下响应时间快速恶化。这就像一个连环套。

我个人的调优顺序是:先砍证书链长度 → 换快速签名算法 → 优化网络路径 → 再压测并发看短板。别一上来就砸钱加机器,很多时候软优化就能解决问题。