【问题标题】:How to generate requests at a "requests/sec" target rate?如何以“请求/秒”目标速率生成请求?
【发布时间】:2013-04-22 09:01:36
【问题描述】:

假设我的目标是x requests/sec,我想连续生成。我的目标是以大致相同的时间间隔开始这些请求,而不是仅仅生成 x 个请求然后等到 1 秒过去并一遍又一遍地重复整个事情.我没有对这些请求做任何假设,有些可能需要比其他请求更长的时间,这就是为什么我的调度程序线程不会执行请求(或等待它们完成),而是将它们交给足够大的线程池。

现在如果x 在数百或更少的范围内,我可能会使用.net 的Timers 或Thread.Sleep 并使用Stopwatch 检查实际经过的时间。

但如果我想进入数千或数万,我可以尝试使用高分辨率计时器来保持我的大致相同的间隔方法。但这会(在通用操作系统上的大多数编程环境中)意味着一定量的手动编码以及旋转等待等,我不确定采取这条路线是否值得。

扩展初始方法,我可以改为使用 Timer 休眠并在每个 Timer 事件上执行 y 请求,监控每秒实现的实际请求并在运行时微调 y。效果介于“放置所有 x 请求并等待自启动后 1 秒”之间,我试图不这样做,“在开始下一个请求之前或多或少地等待 1/x 秒”。

后者似乎是一个不错的折衷方案,但有什么更容易的方法,同时仍能随着时间的推移在一定程度上均匀分布请求?这一定是由不同的人实施了数百次,但我找不到关于这个问题的好的参考资料。

那么最简单的实现方法是什么?

【问题讨论】:

    标签: timer load-testing


    【解决方案1】:

    一种方法:

    首先找到(在 Windows 上祝你好运)或实现 usleepnanosleep 函数。作为第一步,这可能是(在.net 上)一个简单的Thread.SpinWait() / Stopwatch.Elapsed > x 组合。如果您想变得更高级,请在时间跨度足够大的情况下执行Thread.Sleep(),并且仅使用Thread.SpinWait()进行微调。

    完成后,只需将速率取倒数,您就有了在每个事件之间需要睡觉的时间间隔。您在一个专用线程上执行的基本循环,然后继续

    1. 火灾事件
    2. 睡眠(sleepTime)

    然后每隔 250 毫秒(或更多以获得更快的速率),检查实际达到的速率并调整 sleepTime 间隔,也许通过一些平滑来抑制剧烈的临时波动,像这样

    newRate = max(1, sleepTime / targetRate * actualRate)
    sleepTime = 0.3 * sleepTime + 0.7 * newRate
    

    这会根据您的程序和系统中实际发生的情况进行调整,并弥补调用事件回调所花费的时间,以及回调在同一线程上所做的任何事情等。如果没有这个,您可能会无法获得高精度。

    不用说,如果你的速率太高以至于你不能使用Sleep,但总是要旋转,一个核心将持续旋转。好消息:我们的机器上的内核越来越多,因此一个内核的重要性越来越小:) 更严重的是,正如您在评论中提到的那样,如果您的程序确实有效,您的事件生成器将有更少的时间(并且需要) 浪费循环。

    查看https://github.com/EugenDueck/EventCannon 以获取 .net 中的概念验证实现。它的实现大致如上所述,并作为一个库完成,因此如果您使用 .net,您可以将其嵌入到您的程序中。

    【讨论】:

    • 会检查一下,但也许您可以在答案中描述实现,而不仅仅是指向库。
    • +1 EventCannon 以惊人的准确性工作。我尝试了 500 和 5000 事件/秒范围内的各种值,并且始终下降不到 1%。诚然,对于更高的速率,它会消耗 CPU 周期,但我的程序的其余部分显然是在对每个事件进行实际工作,因此它与大炮竞争周期,这意味着大炮可以燃烧的周期更少。也许可以在不影响精度的情况下降低大炮线程的优先级?无论如何,如果您扩展答案中的描述,我可以考虑接受它,除非出现更好的替代方案。
    • 谢谢。有道理,并且实现效果很好,因此您必须小心不要将请求/秒速率设置得太高,否则您很快就会使目标超载,因为项目开始以不断增长的速度排队。我想“事件大炮”这个名字是有道理的——它是一种危险的工具,不会退缩,除非你在调用线程上执行你的工作,这也是触发的线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多