Gatling stomp 发布/订阅负载测试

Posted

技术标签:

【中文标题】Gatling stomp 发布/订阅负载测试【英文标题】:Gatling stomp pub/sub load testing 【发布时间】:2020-01-16 14:27:23 【问题描述】:

我有 web 服务器 Spring boot + STOMP via WS。 很快这个微服务就会投入生产,我想测量 websocket 在负载下的性能。我想知道我的服务将处理多少用户(并基于该配置自动缩放)

服务是 REST API + STOMP 主题发布者。 我想写这样的场景:

在第一次迭代中产生 1 个用户,通过 websocket 连接,订阅一个主题,然后发布一条消息并验证用户通过 WS 收到它,关闭连接。 在第二次迭代中产生 10 个用户,通过 websocket 连接,订阅一个主题,然后发布一条消息并验证 10 个用户通过 WS 收到它,关闭连接; 在第三次迭代中产生 100 个用户,通过 websocket 连接,订阅一个主题,然后发布一条消息并验证 100 个用户通过 WS 收到它,关闭连接; 等等。

然后,根据统计数据,我会发现有多少用户可以处理我的服务。 目前我可以生成用户,通过 WS 进行连接,仅此而已。 如何创建一定数量的用户并创建单个 http 请求,以触发所有用户订阅的 STOMP 主题上的事件发布?

这是我当前的测试场景。

package computerdatabase

import java.util.concurrent.TimeUnit
import scala.concurrent.duration._

import io.gatling.core.Predef._
import io.gatling.core.check.Check
import io.gatling.http.Predef._
import io.gatling.http.check.ws.WsTextCheck

import scala.concurrent.duration.Duration, FiniteDuration
import scala.util.Random

class TickerSimulation extends Simulation 

  val baseUrl = "https://myserverurl.com"

  val httpProtocol = http
    .baseUrl(baseUrl)
    .inferhtmlResources(BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.woff2""", """.*\.(t|o)tf""", """.*\.png""", """.*detectportal\.firefox\.com.*"""))
    .acceptHeader("*/*")
    .acceptEncodingHeader("gzip, deflate")
    .acceptLanguageHeader("de,en-US;q=0.7,en;q=0.3")
    .userAgentHeader("Mozilla/5.0 (X11; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0")

  def randomServerId(): String = 
    val rand = new Random()
    (1 to 3).map  _ => rand.nextInt(10).toString .mkString
  

  def randomSessionId(): String = 
    Random.alphanumeric.take(8).mkString
  

  val feeder = Iterator.continually(Map(
    "serverId" -> randomServerId(),
    "sessionId" -> randomSessionId()
  ))

  val headers_0 = Map(
    "Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "DNT" -> "1",
    "Pragma" -> "no-cache",
    "Content-Type" -> "application/json",
    "Upgrade-Insecure-Requests" -> "1",
    "Authorization" -> "Basic somebasicauth=")

  val answerCheck = ws.checkTextMessage("Connection acknowledge answer")
    .check(regex("^a.*"))

  val answerEventCheck = ws.checkTextMessage("Game event received")
    .check(regex(".*gameEvent.*"))


  val scn = scenario("WidgetTicker")
    .feed(feeder)
        .exec(http("Get game info ")
          .get("/api/game/35384")
          .headers(headers_0))
        .pause(Random.nextInt(10))
    .exec(ws("WS connection").connect("ws://myserverurl.com/api/sock/$serverId/$sessionId/websocket"))
    .pause(1)
    .exec(ws("Connect via STOMP")
      .sendText("[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]")
      .await(60 seconds)(answerCheck)
    ).pause(3)
    .exec(ws("Subscribe")
      .sendText("""["SUBSCRIBE\nid:sub-0\ndestination:/topic/game/35384\n\n\u0000"]""")
      .await(60 seconds)(answerEventCheck)
    )
    .pause(3)
    .exec(ws("WS close").close)


  setUp(scn.inject(
    atOnceUsers(1000)
  )).protocols(httpProtocol)


【问题讨论】:

【参考方案1】:

我创建了一个主题,服务器每隔几秒就会写入一次。 然后我在模拟期间验证用户是否收到此消息。并以这种方式测试 pub/sub WebSocket 连接

这是我想出的:

val answerEventCheck = ws.checkTextMessage("Game event received")
    .check(regex("""^a.*topic\/game\/123.*"""))


val scn = scenario("WidgetTicker")
    .feed(feeder)
    .exec(ws("WS connection").connect("ws://$baseUrl/api/sock/$serverId/$sessionId/websocket"))
    .pause(1)
    .exec(ws("Connect via STOMP")
      .sendText("[\"CONNECT\\naccept-version:1.1,1.0\\nheart-beat:10000,10000\\n\\n\\u0000\"]")
      .await(3 seconds)(answerCheck)
    ).pause(3)
    .exec(ws("Subscribe")
      .sendText("[\"SUBSCRIBE\\nid:sub-0\\ndestination:/topic/game/123\\n\\n\\u0000\"]")
      .await(5 seconds)(answerEventCheck)
    )
    .pause(5)
    .exec(ws("WS close").close)

【讨论】:

以上是关于Gatling stomp 发布/订阅负载测试的主要内容,如果未能解决你的问题,请参考以下文章

如何并行调用多个 API 进行负载测试(使用 Gatling)?

负载,性能测试工具-Gatling

如何在 Gatling 负载测试中为多个虚拟用户使用单个 OAuth2.0 令牌

使用gatling做压力测试与负载测试

负载测试应用程序调用外部 http 服务

加特林负载测试 - XML 文件作为饲料可能?