Http负载测试

时间:2017-12-12 04:30:47

标签: scala akka microservices akka-http

我正在尝试创建一个可以一次处理100万个请求的简单微服务。但我在客户端遇到连接重置错误。如果我犯了任何错误,请纠正我。

服务器代码 1. 听众

  object Collection {
  case class calculate(values:Double)
 }

 object EngineController{

 import Collection._


def main(args: Array[String]): Unit = {
try {
  implicit val system = ActorSystem()
  implicit val materializer = ActorMaterializer()
  implicit val executionContext = system.dispatcher
val requestHandler = system.actorOf(RoundRobinPool(3).props(RequestHandler.props), "round-robin-pool")
  val route: Route = {
    implicit val timeout = Timeout(100.seconds)
    path("aggregate") {
      log.info("REQUEST RECEIVED")
      post {
        entity(as[String]) { values =>
          onSuccess(requestHandler ? calculate(values)) {
            case result: Double =>
              log.info("Response Sent -" + result)
              complete(s"${result}")

          }
        }
      }
    } 
  }
  val routeBinding :Future[ServerBinding] = Http().bindAndHandle(route, "localhost", 8080)
  log.info("Connection Established! Waiting for Request")
  routeBinding.failed.foreach { ex =>
    log.error(ex, "Failed to bind to {}:{}!", host, port)
  }
  StdIn.readLine()

  routeBinding.flatMap(_.unbind())
  system.terminate()

}

catch {
  case ex: Exception =>
    log.error(ex, ex)
}
}
}
  1. RequestHandler:此actor返回数字的最大值。

    object RequestHandler extends App {
    def props: Props = {
    Props(classOf[RequestHandler])
      }
    
    class RequestHandler extends Actor {
    var doubleArray: Array[Double] = Array.empty
    val system1 = ActorSystem("system2")
    var routees: List[ActorRef] = _
    override def preStart() = {
    routees = List.fill(5)(
    context.actorOf(AggregateCalculator.props)
    )
    }
    val aggregateActor = system1.actorOf(AggregateCalculator.props.withRouter(RandomPool(100)), "ag")
    
     //CONVERT STRING TO ARRAY
     def stringToArray(values: String): Array[Double] = {
     return values.split(",").map(x => x.toDouble)
     }
    
     override def receive: Receive = {
     case calculate(values) =>
     doubleArray = stringToArray(values)
     sender() ! doubleArray.max
       }
      }
     }
    
  2. 客户代码

     package Test
     import scalaj.http.{Http, HttpResponse}
     import org.apache.log4j.Logger
    
    
     //libraryDependencies += "org.scalaj" % "scalaj-http_2.11" % "2.3.0"
     object RequestSender1 {
    val log = Logger.getLogger(getClass.getName)
    def main(args: Array[String]): Unit = {
    try {
      val str = "22.78, -1.23, 50, 60, 3, 32, 11, 54, 72, 78, 99, 70, 19, 47, 90, 81, 50, 69, 69, 72, 83, 14.7, 8, 41, 65, 73, 48, 63, 47, 17, 55, 39, 50, 87, 76, 8, 67, 51, 55, 94, 75, 14, 91, 35, 87, 36, 42, 74, 70, 81, 18, 14, 50, 22, 16, 55, 71, 17, 39, 44, 58, 61, 16, 4, 74, 61, 37, 31, 62, 36, 53, 30, 82, 72, 89, 96, 28, 36, 77, 89, 30, 2, 31, 79, 50, 34, 81, 39, 91, 85, 94, 25, 68, 98, 46, 42,14,14"
      var result: HttpResponse[String] = null
      var counter = 0
      for (i <- 1 to 300) {
    
        for (i <- 1 to 13000) {
          val thread = new Thread {
            override def run {
              while (counter < 1000024) {
                try {
                  counter += 1
                  result = scalaj.http.Http("http://localhost:8080/aggregate").postData(str).timeout(1200000, 120000000) //192.168.0.157:8089
                    .header("Content-Type", "text/plain").asString
                  println("Thread Count----" + java.lang.Thread.activeCount())
                  j += 1
                  println(result.body + "   " + j)
                } catch {
                  case ex:Exception =>
                    log.error(ex)
                }
              }
            }
          }
          thread.start
          // slow the loop down a bit
        }
        println("Sent request with --" + i)
        Thread.sleep(1)
        // slow the loop down a bit
     }
    }
    catch {
      case ex:Exception =>
        println("Exception"+">>>>>>>>>>")
    }
    

    } }

    错误1

    09:58:07 ERROR [Thread-12803] - Test.RequestSender1$.run 32 - java.net.BindException: Address already in use: connect
    

    错误2

    Thread-12418" java.net.SocketException: Connection reset
    

    对不良对齐

1 个答案:

答案 0 :(得分:0)

我认为这与Scala或HTTP无关。这是TCP协议的限制。

不幸的是,您无法从一台计算机创建100万个出站TCP连接。 TCP连接由客户端和服务器的两对(IP地址,端口)指定。服务器可能具有到达同一端口的所有连接,并通过客户端信息区分它们。但是对于任何典型的TCP / IP实现,每个出站连接都会分配给它自己唯一的TCP端口(即使您推出了一些自定义实现,您仍然无法从同一客户端连接到同一服务器/端口的两个传出连接/ port因为它们无法区分)。 TCP port实际上只是一个16位数字。这意味着总共只有大约65,000个端口,这显然远远少于你想要的100万个。因此,要建立100万个连接,您需要同时运行测试的许多计算机(或至少是虚拟机)。