zoukankan      html  css  js  c++  java
  • Gatling-插件开发


    源码

    参考:
    How to Write a Custom Protocol for Gatling?
    Creating a custom Gatling prococol for AWS Lambda

    插件开发

    Action

    package io.gatling.ext.redis.action
    
    import java.util.concurrent.Executors
    
    import com.typesafe.scalalogging.StrictLogging
    import io.gatling.commons.stats.{KO, OK}
    import io.gatling.commons.util.Clock
    import io.gatling.core.CoreComponents
    import io.gatling.core.action.{Action, ExitableAction}
    import io.gatling.core.session.{Expression, Session}
    import io.gatling.core.stats.StatsEngine
    import io.gatling.core.util.NameGen
    import io.gatling.ext.redis.protocol.RedisComponents
    import redis.clients.jedis.Jedis
    
    import scala.concurrent._
    import scala.util.{Failure, Success}
    
    
    class RedisGetAction(
                          key: Expression[String],
                          coreComponents: CoreComponents,
                          val redisComponents: RedisComponents,
                          throttled: Boolean,
                          val next: Action
                        ) extends ExitableAction with NameGen with StrictLogging {
    
      // 可以自定义也可以引入默认的执行器
      // import scala.concurrent.ExecutionContext.Implicits.global
      implicit val ec: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(50))
    
      override def statsEngine: StatsEngine = coreComponents.statsEngine
    
      override def clock: Clock = coreComponents.clock
    
      override def name: String = genName("redis-get-action")
    
      override def execute(session: Session): Unit = {
    
        key(session) map {
    
          keyS => {
    
            val requestStartDate = clock.nowMillis
    
            val jedis: Jedis = redisComponents.jedisMap(session.userId)
    
            val future: Future[String] = Future[String] {
              jedis.get(keyS)
            }
    
            future onComplete {
              case Success(value) => statsEngine.logResponse(
                session,
                keyS,
                requestStartDate,
                clock.nowMillis,
                OK,
                Some(value),
                Some(value)
              )
              case Failure(exception) => {
                logger.error(exception.toString)
                statsEngine.logResponse(
                  session,
                  keyS,
                  requestStartDate,
                  clock.nowMillis,
                  KO,
                  Some(exception.getMessage),
                  Some(exception.getMessage)
                )
              }
            }
    
            if (throttled) {
              coreComponents.throttler.throttle(session.scenario, () => next ! session)
            } else {
              next ! session
            }
          }
        }
      }
    }
    

    ActionBuilder

    package io.gatling.ext.redis.builder
    
    import com.typesafe.scalalogging.StrictLogging
    import io.gatling.core.action.Action
    import io.gatling.core.action.builder.ActionBuilder
    import io.gatling.core.session.Expression
    import io.gatling.core.structure.ScenarioContext
    import io.gatling.ext.redis.action.RedisGetAction
    import io.gatling.ext.redis.protocol.RedisProtocol
    
    class RedisActionBuilder(key: Expression[String]) extends ActionBuilder with StrictLogging {
    
      override def build(ctx: ScenarioContext, next: Action): Action = {
    
        import ctx._
        new RedisGetAction(
          key,
          coreComponents,
          protocolComponentsRegistry.components(RedisProtocol.redisProtocolKey),
          throttled,
          next
        )
      }
    }
    

    Protocol & Components & Components

    package io.gatling.ext.redis.protocol
    
    import io.gatling.core.config.GatlingConfiguration
    import io.gatling.core.protocol.{Protocol, ProtocolComponents, ProtocolKey}
    import io.gatling.core.session.Session
    import io.gatling.core.{CoreComponents, protocol}
    import redis.clients.jedis.Jedis
    
    case class RedisProtocol(host: String, port: Int, password: Option[String]) extends Protocol {
      type Components = RedisComponents
    }
    
    object RedisProtocol {
    
      def apply(host: String, port: Int, password: Option[String] = None): RedisProtocol = new RedisProtocol(host, port, password)
    
      val redisProtocolKey: ProtocolKey[RedisProtocol, RedisComponents] = new ProtocolKey[RedisProtocol, RedisComponents] {
    
        override def protocolClass: Class[protocol.Protocol] = classOf[RedisProtocol].asInstanceOf[Class[io.gatling.core.protocol.Protocol]]
    
        override def defaultProtocolValue(configuration: GatlingConfiguration): RedisProtocol = RedisProtocol("127.0.0.1", 6379)
    
        override def newComponents(coreComponents: CoreComponents): RedisProtocol => RedisComponents = {
          redisProtocol => RedisComponents(redisProtocol)
        }
      }
    }
    
    case class RedisComponents(redisProtocol: RedisProtocol) extends ProtocolComponents {
    
      val jedisMap: scala.collection.mutable.Map[Long, Jedis] = scala.collection.mutable.HashMap()
    
      override def onStart: Session => Session = {
        session => {
          println("RedisComponents start: " + session)
          val jedis: Jedis = new Jedis(redisProtocol.host, redisProtocol.port)
    
          redisProtocol.password match {
            case Some(value) => jedis.auth(value)
            case None =>
          }
    
          jedis.set(String.valueOf(session.userId), session.toString)
    
          jedisMap(session.userId) = jedis
    
          session
        }
      }
    
      override def onExit: Session => Unit = {
        session => {
          println("RedisComponents exit: " + session)
        }
      }
    }
    
    case class RedisProtocolBuilder(host: String, port: Int, password: Option[String]) {
      def build: RedisProtocol = RedisProtocol(host, port, password)
    }
    
    object RedisProtocolBuilder {
      implicit def toRedisProtocol(builder: RedisProtocolBuilder): RedisProtocol = builder.build
    }
    

    Predef

    package io.gatling.ext.redis
    
    import io.gatling.core.session.Expression
    import io.gatling.ext.redis.builder.RedisActionBuilder
    import io.gatling.ext.redis.protocol.RedisProtocolBuilder
    
    object Predef {
    
      implicit def string2Option(string: String): Option[String] = Some(string)
      
      def redis(
                 host: String,
                 port: Int,
                 password: Option[String] = None
               ): RedisProtocolBuilder = RedisProtocolBuilder(host, port, password)
    
      def redis(key: Expression[String]): RedisActionBuilder = new RedisActionBuilder(key)
    }
    

    使用中遇到的问题

    如果要在DSL中使用hours、minutes等,需要导包:scala.concurrent.duration._
    Expression的本质是一个函数:session => type Expression[T] = Session => Validation[T]
    Validation中常用的两个函数:
    1. def map[A](f: T => A): Validation[A]
    2. def flatMap[A](f: T => Validation[A]): Validation[A]
  • 相关阅读:
    CNN comprehension
    Gradient Descent
    Various Optimization Algorithms For Training Neural Network
    gerrit workflow
    jenkins job配置脚本化
    Jenkins pipeline jobs隐式传参
    make words counter for image with the help of paddlehub model
    make words counter for image with the help of paddlehub model
    git push and gerrit code review
    image similarity
  • 原文地址:https://www.cnblogs.com/CSunShine/p/12737746.html
Copyright © 2011-2022 走看看