我意识到这个问题很老了,但是我在为了自己研究类似的问题时遇到了它,并且认为我会分享我达到的解决方案,以防其他人遇到类似的问题。我的情况并不完全相似,但我的问题的核心本质是在并行运行的两个场景之间传递数据,所以我希望答案将来对其他人有一些价值,尽管它在技术上只回答了原始问题的一半问题。
以下设置显示了两个场景如何一起运行的总体思路,其中第二个场景以延迟开始,以确保场景 1 中已生成数据:
setUp(
scenario1.inject(constantUsersPerSecond(0.5) during (10 minutes)),
scenario2.inject(nothingFor(3 minutes), constantUsersPerSecond(0.1) during (7 minutes))
).protocols(httpProtocol)
简单地合并这两个场景是可能的,但我将这两个场景定义在两个单独的类中,因为它们的大小,因为这两个场景都由一长串执行步骤组成,并且由于它们需要与不同的注射曲线并行运行。场景 2 中所需的数据在场景 1 中生成并存储在其会话中。
为了将数据从一个场景传递到另一个场景,我创建了一个对象,除了保存单个场景之外,该对象绝对不执行任何操作链接阻塞双端队列物品。我选择了这种集合类型,希望能够在运行高负载测试时避免任何并发问题。
import java.util.concurrent.LinkedBlockingDeque
object DequeHolder {
val DataDeque = new LinkedBlockingDeque[String]()
}
在场景一中,我在该场景的每个成功循环结束时将值保存到此双端队列:
val saveData = exec{ session =>
DataDequeHolder.DataDeque.offerLast(session("data").as[String])
session
}
val scenario1 = scenario("Scenario 1")
.exec(
step1,
step2,
.....
stepX,
saveData
)
最后,在场景二中,我创建了一个自定义馈送器,用于从 LinkBlockingDeque 检索数据,并像使用任何其他馈送器一样使用此馈送器:
class DataFeeder extends Feeder[String] {
override def hasNext: Boolean = DataDequeHolder.DataDeque.size() > 0
override def next(): Map[String, String] = Map("data" -> DataDequeHolder.DataDeque.takeFirst())
}
val scenario2 = scenario("Scenario 2")
.feed(new DataFeeder())
.exec(
step1,
step2,
.....
stepX,
)
到目前为止,这已被证明是在两个场景之间传递数据且不会遇到并发问题的可靠方法。然而值得注意的是,我没有在高负载下运行它,因为我的后端系统运行一些非常繁重的操作,并且不打算与数千个并发用户一起运行。我不知道这对于高负载下的系统将如何发挥作用。