在gatling中使用scala迭代器时出现并发错误

时间:2015-06-03 12:25:09

标签: scala akka gatling

我正在使用gatling来运行负载测试。我不是一个gatling或scala专家,但在我看来,这个特殊的问题可能与scala(和Akka)更有关,而不是与gatling本身相关。我将从最后开始:当在一台不那么强大的机器上高负载运行时,我偶尔会遇到这个错误:

  

07:04:42.071 [错误]   i.g.c.a.b.SessionHookBuilder $$ anonfun $ build $ 1 $$ anon $ 1 -   'sessionHook-29'在会话中崩溃了   会议(searchOrder,5348761459522421680-8295,地图(),1433329482056,0,   好的,List(),),转发到下一个   java.lang.UnsupportedOperationException:空列表的尾部           at scala.collection.immutable.Nil $ .tail(List.scala:422)〜[scala-library-2.11.6.jar:na]           在scala.collection.immutable.Nil $ .tail(List.scala:417)〜[scala-library-2.11.6.jar:na]           在scala.collection.LinearSeqLike $$ anon $ 1.next(LinearSeqLike.scala:46)   〜[阶库-2.11.6.jar:NA]           在scala.collection.TraversableOnce $ FlattenOps $$ anon $ 1.next(TraversableOnce.scala:450)   〜[阶库-2.11.6.jar:NA]           at MyNamespace.Tenants $ .next(Tenants.scala:21)〜[na:na]           at MyNamespace.LoadTests $$ anonfun $ run $ 1.apply(LoadTests.scala:43)   〜[NA:NA]           在MyNamespace.LoadTests $$ anonfun $ run $ 1.apply(LoadTests.scala:41)   〜[NA:NA]           at io.gatling.core.action.SessionHook.executeOrFail(SessionHook.scala:35)   〜[格林 - 芯 - 2.1.5.jar:2.1.5]           at io.gatling.core.action.Failable $ class.execute(Actions.scala:71)   〜[格林 - 芯 - 2.1.5.jar:2.1.5]           在io.gatling.core.action.SessionHook.execute(SessionHook.scala:28)   〜[格林 - 芯 - 2.1.5.jar:2.1.5]           at io.gatling.core.action.Action $$ anonfun $ receive $ 1.applyOrElse(Actions.scala:29)   〜[格林 - 芯 - 2.1.5.jar:2.1.5]           在scala.PartialFunction $ OrElse.applyOrElse(PartialFunction.scala:171)   〜[阶库-2.11.6.jar:NA]           at akka.actor.Actor $ class.aroundReceive(Actor.scala:465)〜[akka-actor_2.11-2.3.9.jar:na]           在io.gatling.core.akka.BaseActor.aroundReceive(BaseActor.scala:22)   〜[格林 - 芯 - 2.1.5.jar:2.1.5]           at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)〜[akka-actor_2.11-2.3.9.jar:na]           at akka.actor.ActorCell.invoke(ActorCell.scala:487)〜[akka-actor_2.11-2.3.9.jar:na]           at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254)〜[akka-actor_2.11-2.3.9.jar:na]           at akka.dispatch.Mailbox.run(Mailbox.scala:221)〜[akka-actor_2.11-2.3.9.jar:na]           at akka.dispatch.Mailbox.exec(Mailbox.scala:231)〜[akka-actor_2.11-2.3.9.jar:na]           在scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)   〜[阶库-2.11.6.jar:NA]           在scala.concurrent.forkjoin.ForkJoinPool $ WorkQueue.runTask(ForkJoinPool.java:1339)   〜[阶库-2.11.6.jar:NA]           在scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)   [阶库-2.11.6.jar:NA]           在scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)   [阶库-2.11.6.jar:NA]

我怀疑它与使用

有关
Iterator.continually([some collection]).flatten

其中[some collection]是我试图循环循环的集合。可能是因为当许多并发线程试图访问以这种方式定义的迭代器时偶尔会失败?有没有更好的方法来创建一个也是线程安全的循环迭代器?

与下面的“save”方法创建的租户对象一样(实际上这里有更多代码填充get方法检索的集合,因此它实际上永远不会为空):

import io.gatling.core.Predef._

object Tenants {
  type TenantKeys = Map[String, Map[String, String]]
  val key = "tenants"
  val elementKey = "tenant"
  var tenants: Iterator[Map[String, String]] = Iterator(Map[String, String]())

  def get(session: Session): TenantKeys = {
    session(key)
      .asOption[TenantKeys]
      .getOrElse(Map[String, Map[String, String]]())
  }

  def save(session: Session): Session = {
    val mapped = get(session).map(_._2).toSeq
    tenants = Iterator.continually(mapped).flatten
    session
  }
}

1 个答案:

答案 0 :(得分:0)

你所做的不仅仅是工作。这不是Scala的问题,而是并发编程之一。 就像Java Iterators一样,Scala也不是线程安全的。

使用Gatling的feed()是线程安全的。