服务过载时请求队列该怎么处理?队满丢哪一个?背压怎么把下游的慢传回上游?这篇用本进程里的服务模型和流水线,把吞吐曲线、几种丢弃策略和背压的效果量出来。
到达速率 | 无保护:成功速率 | p99 | 白干(处理完时已超时) | 有保护:成功速率 | p99 | 丢掉的(拒绝 + 过期) ------+----------+--------+-------------+----------+--------+------------- 100/s | 100/s | 30 ms | 0 | 100/s | 31 ms | 0 200/s | 20/s | 505 ms | 685 | 152/s | 368 ms | 238 300/s | 0/s | - | 836 | 153/s | 373 ms | 832 400/s | 0/s | - | 880 | 155/s | 372 ms | 1421 600/s | 0/s | - | 907 | 155/s | 366 ms | 2617 800/s | 0/s | - | 916 | 157/s | 371 ms | 3805
无保护的队列越积越长,排到的请求都已过截止时间,成功速率塌到 0;有保护稳定在容量上。
做法 | 成功速率 | 成功请求延迟中位数 | p99 | 高优先级成功比例 | 低优先级成功比例 | 白干(处理完时已超时) ------------+-------+-----------+--------+----------+----------+------------ 无界 FIFO | 0/s | - | - | 0% | 0% | 875 tail-drop | 154/s | 350 ms | 368 ms | 36% | 39% | 0 head-drop | 160/s | 149 ms | 315 ms | 41% | 40% | 0 LIFO + 丢最老的 | 164/s | 28 ms | 415 ms | 41% | 41% | 3 随机丢 | 159/s | 218 ms | 332 ms | 38% | 40% | 0 按优先级丢 | 156/s | 270 ms | 333 ms | 100% | 24% | 0
总成功速率差不多,区别在延迟分布和谁被牺牲;LIFO 让多数请求很快,按优先级丢保住高优先级。
队列 | 上游 6 秒生产了 | 上游实际速率 | 每秒的队列长度 | 最后 300 个任务排队时间的中位数 | 最长排队时间 | 上游停止时队里还剩 ---------------+-----------+--------+---------------------------------+--------------------+---------+---------- 无界 | 3001 | 500/s | [0, 353, 706, 1060, 1415, 1773] | 4910 ms | 5662 ms | 1834 有界(100)+阻塞 put | 967 | 161/s | [0, 100, 100, 100, 100, 100] | 699 ms | 739 ms | 0 有界队列把下游的慢直接传导给上游:上游被 put 阻塞,速率降到下游的处理能力;无界队列把这个差额存起来,变成越来越长的排队时间(和内存)
有界队列加阻塞把下游的慢传给上游;无界队列把差额存起来变成排队时间和内存。