Gatling 在测试长轮询 HTTP 请求时抛出 InvalidActorNameException

Gatling throws InvalidActorNameException when testing long-poll HTTP requests

我有一个带有两个 HTTP 端点的类似聊天的服务:

POST 请求 returns 如果在最后 N 分钟内没有注册的侦听器,则错误,因此我必须先进行长轮询 GET 请求。 我正在尝试使用 Gatling 的 poll 功能,但我收到一些虚拟用户的 InvalidActorNameException

val scn = scenario("Chat").
    feed(csv("users.csv").random).
    exec(session => session.set("test-user-name","${userEmail}")).
    exec(authenticateInSamlService).
    exec(
      polling.
        every(100 millis).
        exec(
          http("Poll Chat Mesages").
            get("/chat/poll/")
            queryParam("test-user-name","${test-user-name}")
            header("X-Session-Id", "Session0")
            check status.is(200)
            check bodyString.is("YOMOMMA")
        )
    ).
    pause(2 seconds).
    exec(
      http("Send Chat Messag").
        post("/chat/")
        queryParam("test-user-name","${test-user-name}")
        header("Content-Type", "application/octet-stream")
        header("X-Session-Id", "Session2")
        body StringBody("YOMOMMA")
        check status.is(201)
    ).
    pause(2 seconds).
    exec(polling.stop)

setUp(scn.inject(
    atOnceUsers(1),
    rampUsers(20) over (20 seconds)
  ).protocols(httpConf))

完整的异常堆栈跟踪是

akka.actor.InvalidActorNameException: actor name [gatling.http.polling-5-actor] is not unique!
    at akka.actor.dungeon.ChildrenContainer$NormalChildrenContainer.reserve(ChildrenContainer.scala:129)
    at akka.actor.dungeon.Children$class.reserveChild(Children.scala:130)
    at akka.actor.ActorCell.reserveChild(ActorCell.scala:374)
    at akka.actor.dungeon.Children$class.makeChild(Children.scala:268)
    at akka.actor.dungeon.Children$class.attachChild(Children.scala:46)
    at akka.actor.ActorCell.attachChild(ActorCell.scala:374)
    at akka.actor.ActorSystemImpl.actorOf(ActorSystem.scala:589)
    at io.gatling.http.action.async.polling.PollingStart.startPolling(PollingStart.scala:55)
    at io.gatling.http.action.async.polling.PollingStart.io$gatling$http$action$async$polling$PollingStart$$$anonfun(PollingStart.scala:67)
    at io.gatling.http.action.async.polling.PollingStart.io$gatling$http$action$async$polling$PollingStart$$$anonfun$adapted(PollingStart.scala:67)
    at io.gatling.commons.validation.Success.map(Validation.scala:32)
    at io.gatling.http.action.async.polling.PollingStart.execute(PollingStart.scala:67)
    at io.gatling.core.action.Action$class.$bang(Action.scala:35)
    at io.gatling.http.action.async.polling.PollingStart.io$gatling$core$action$ChainableAction$$super$$bang(PollingStart.scala:30)
    at io.gatling.core.action.ChainableAction$class.$bang(Action.scala:60)
    at io.gatling.http.action.async.polling.PollingStart.io$gatling$core$action$ExitableAction$$super$$bang(PollingStart.scala:30)
    at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun(BlockExit.scala:140)
    at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$adapted(BlockExit.scala:140)
    at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:125)
    at io.gatling.core.action.ExitableAction$class.$bang(BlockExit.scala:140)
    at io.gatling.http.action.async.polling.PollingStart.$bang(PollingStart.scala:30)
    at io.gatling.core.action.SessionHook.io$gatling$core$action$SessionHook$$$anonfun(SessionHook.scala:38)
    at io.gatling.core.action.SessionHook.io$gatling$core$action$SessionHook$$$anonfun$adapted(SessionHook.scala:38)
    at io.gatling.commons.validation.Success.map(Validation.scala:32)
    at io.gatling.core.action.SessionHook.execute(SessionHook.scala:38)
    at io.gatling.core.action.Action$class.$bang(Action.scala:35)
    at io.gatling.core.action.SessionHook.io$gatling$core$action$ChainableAction$$super$$bang(SessionHook.scala:30)
    at io.gatling.core.action.ChainableAction$class.$bang(Action.scala:60)
    at io.gatling.http.action.sync.AddCookieBuilder$$anon.io$gatling$core$action$ExitableAction$$super$$bang(AddCookieBuilder.scala:77)
    at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun(BlockExit.scala:140)
    at io.gatling.core.action.ExitableAction$class.io$gatling$core$action$ExitableAction$class$$$anonfun$adapted(BlockExit.scala:140)
    at io.gatling.core.action.ExitableAction$.exitOrElse(BlockExit.scala:125)
    at io.gatling.core.action.ExitableAction$class.$bang(BlockExit.scala:140)
    at io.gatling.http.action.sync.AddCookieBuilder$$anon.$bang(AddCookieBuilder.scala:77)
    at io.gatling.http.ahc.ResponseProcessor.executeNext(ResponseProcessor.scala:144)
    at io.gatling.http.ahc.ResponseProcessor.logAndExecuteNext(ResponseProcessor.scala:169)
    at io.gatling.http.ahc.ResponseProcessor.checkAndProceed(ResponseProcessor.scala:291)
    at io.gatling.http.ahc.ResponseProcessor.processResponse(ResponseProcessor.scala:321)
    at io.gatling.http.ahc.ResponseProcessor.onCompleted(ResponseProcessor.scala:61)
    at io.gatling.http.ahc.AsyncHandler.onCompleted(AsyncHandler.scala:127)
    at io.gatling.http.ahc.AsyncHandler.onCompleted(AsyncHandler.scala:46)
    at org.asynchttpclient.netty.NettyResponseFuture.getContent(NettyResponseFuture.java:188)
    at org.asynchttpclient.netty.NettyResponseFuture.done(NettyResponseFuture.java:223)
    at org.asynchttpclient.netty.handler.HttpHandler.finishUpdate(HttpHandler.java:58)
    at org.asynchttpclient.netty.handler.HttpHandler.handleChunk(HttpHandler.java:159)
    at org.asynchttpclient.netty.handler.HttpHandler.handleRead(HttpHandler.java:189)
    at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:82)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:428)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:277)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:264)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:243)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:240)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1070)
    at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:904)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:387)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:245)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:292)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:278)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:962)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
    at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:112)
    at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    at java.lang.Thread.run(Thread.java:745)

我可以使用 Gatling 来测试长轮询请求吗?它还不受支持吗?

确实是一个错误,感谢报告。 固定:https://github.com/gatling/gatling/issues/2970