---
title: 测量、压测与离散事件仿真
url: https://doc.liz6.com/theory/03-queueing-theory/10-measurement-and-simulation
locale: zh
area: theory
tags:
- 排队论
- 基础理论
date: 2026-09-10
modified: 2026-09-10
description: 公式是否适用，要靠测量和可复现实验检验。好的压测不仅报告“完成了多少”，还记录原本计划到达多少、在哪里等待，以及窗口结束时哪些请求还没完成。
---

# 测量、压测与离散事件仿真

公式是否适用，要靠测量和可复现实验检验。好的压测不仅报告“完成了多少”，还记录原本计划到达多少、在哪里等待，以及窗口结束时哪些请求还没完成。

## 开放与封闭负载

固定并发用户通常是完成一次才发下一次，属于封闭负载；开放模型按预定速率调度到达，不因系统变慢而主动减慢计划。两者都合理，取决于真实用户行为。[k6 官方文档](https://grafana.com/docs/k6/latest/using-k6/scenarios/concepts/open-vs-closed/)明确区分这两类执行方式。

举一个确定性例子：每 10 ms 计划发一个请求，服务端暂停 100 ms。若生成器等上一次完成后才继续发，暂停期间原本应到达的多个请求根本没有样本，这就是 coordinated omission 的典型来源。仅记录实际发送到完成的时间，还可能漏掉生成器内部从计划时刻到实际发送的延迟。

至少保存计划时刻、实际发送时刻、接纳、服务开始和最终结果。开放生成器也可能耗尽虚拟用户、CPU、连接或网络；应报告漏发/延迟发出的次数以及实际到达率。[HdrHistogram](https://github.com/HdrHistogram/HdrHistogram)提供按预期间隔修正遗漏的功能，但修正依赖负载模型，不能恢复任意真实流量的全部事实。

## 离散事件无需按帧推进

单台 FIFO 可直接使用递推：

$$W_{q,i+1}=\max(0,W_{q,i}+S_i-I_{i+1}).$$

等价实现是 $b_i=\max(a_i,d_{i-1})$、$d_i=b_i+S_i$。时间直接跳到到达或完成事件，不需要每毫秒循环；同刻事件的顺序必须固定。[SimPy 的调度说明](https://simpy.readthedocs.io/en/latest/topical_guides/time_and_scheduling.html)解释模拟时间与确定事件顺序的区别。本实验独立实现递推，不依赖屏幕刷新。

```python
# arrivals 和 service 是同一单位的独立生成序列
end = 0.0
samples = []
for arrival, service_time in zip(arrivals, service):
    start = max(arrival, end)
    end = start + service_time
    samples.append((arrival, start, end))
```

## 预热、删失和到达群

空系统起步的早期请求可能等待偏低。实验丢弃前 20% 到达作为预热，但这只是明确的规则，未证明在高利用率下足够长。截止设在最后一个请求到达的时刻；随后继续服务到全部完成。

同时报告预热后**全部到达者**的完整均值，以及只取截止前完成者的均值。后一组遗漏尚未完成者，可能低估时延，具体单次差异受轨迹影响。FIFO 中停止新增到达不会改变已经排队请求的完成时刻，因此排空可以恢复这个到达群的完整时延；对依赖未来到达的优先级调度不能照搬此论证。

**测量、压测与离散事件仿真 · 实验**

空系统开始的M/M/1，μ=100/s；固定种子生成到达与服务，丢弃前20%到达作为预热。截止为最后一次到达，继续排空以取得完整到达群。预热长度不保证已达稳态，单次结果不是置信区间。


先固定种子改变负载，再更换种子看随机波动。经验曲线在有限网格上显示超过阈值的样本比例；理论线为稳态 M/M/1 的精确尾部。样本 p99 用排序后第 $\lceil0.99n\rceil$ 个值。理论与单次仿真不必重合，仿真也不是对真实系统模型正确性的证明。

## 让结果可用于决策

使用多个独立重复，报告每轮参数、种子、预热、观测长度与不确定性。请求等待常有序列相关，不能把一长串相邻请求当成独立样本随意构造窄置信区间；可研究独立重复或满足条件的批均值方法。接近饱和时，需更长的相关时间和恢复观察。

测量同时保留成功、拒绝、超时、取消、未完成数量及不同类别分布。超时是“超过某阈值仍未获结果”的信息，不能随便记成精确完成时延。聚合多个实例的 p99 不能直接平均；应合并兼容直方图或原始样本后求分位数，并声明桶精度和计数口径。

## 自检

1. 1000 个样本估计 p99，大致依靠多少个上尾样本？

<details><summary>参考思路</summary>

约 10 个。少数慢请求的变化就能显著改变估计，还要考虑相关性、预热和删失。不能因为输出了三位小数，就认为尾部已经测得精确。

</details>

2. 固定种子后两次得到相同 p99，是否已经证明仿真正确？

<details><summary>参考思路</summary>

只证明可复现。还需用手算轨迹验证事件顺序、用独立计算核对统计、用已知稳态模型检查长运行表现，并检查不稳定和边界情况。可复现的错误仍然是错误。

</details>
