Я выполняю нагрузочное тестирование на платформе Akka-http (версия: 10.0), я использую инструмент wrk. Команда WRK:Akka Http Performance tuning
wrk -t6 -c10000 -d 60s --timeout 10s --latency http://localhost:8080/hello
первый запуск без блокировки вызова,
object WebServer {
implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()
implicit val executionContext = system.dispatcher
def main(args: Array[String]) {
val bindingFuture = Http().bindAndHandle(router.route, "localhost", 8080)
println(
s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine() // let it run until user presses return
bindingFuture
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
}
}
object router {
implicit val executionContext = WebServer.executionContext
val route =
path("hello") {
get {
complete {
"Ok"
}
}
}
}
выход WRK:
Running 1m test @ http://localhost:8080/hello
6 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.22ms 16.41ms 2.08s 98.30%
Req/Sec 9.86k 6.31k 25.79k 62.56%
Latency Distribution
50% 3.14ms
75% 3.50ms
90% 4.19ms
99% 31.08ms
3477084 requests in 1.00m, 477.50MB read
Socket errors: connect 9751, read 344, write 0, timeout 0
Requests/sec: 57860.04
Transfer/sec: 7.95MB
Теперь, если я добавить будущий вызов в маршруте и повторите тест.
val route =
path("hello") {
get {
complete {
Future { // Blocking code
Thread.sleep(100)
"OK"
}
}
}
}
выход, из WRK:
Running 1m test @ http://localhost:8080/hello
6 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 527.07ms 491.20ms 10.00s 88.19%
Req/Sec 49.75 39.55 257.00 69.77%
Latency Distribution
50% 379.28ms
75% 632.98ms
90% 1.08s
99% 2.07s
13744 requests in 1.00m, 1.89MB read
Socket errors: connect 9751, read 385, write 38, timeout 98
Requests/sec: 228.88
Transfer/sec: 32.19KB
Как вы можете видеть в будущем вызова только 13744 запросы обслуживаются.
После следующего Akka documentation я добавил отдельный пул диспетчерских потоков для маршрута, который создает максимум, 200 потоков.
implicit val executionContext = WebServer.system.dispatchers.lookup("my-blocking-dispatcher")
// config of dispatcher
my-blocking-dispatcher {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
// or in Akka 2.4.2+
fixed-pool-size = 200
}
throughput = 1
}
После указанного изменения, производительность улучшилась немного
Running 1m test @ http://localhost:8080/hello
6 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 127.03ms 21.10ms 504.28ms 84.30%
Req/Sec 320.89 175.58 646.00 60.01%
Latency Distribution
50% 122.85ms
75% 135.16ms
90% 147.21ms
99% 190.03ms
114378 requests in 1.00m, 15.71MB read
Socket errors: connect 9751, read 284, write 0, timeout 0
Requests/sec: 1903.01
Transfer/sec: 267.61KB
В мой блокирующие-диспетчерских конфигурациях, если я увеличить размер пула выше 200 производительность же.
Теперь, какие другие параметры или настройки следует использовать для увеличения производительности при использовании будущего вызова. Так что это приложение дает максимальную пропускную способность.
Очень хороший анализ. –
Итак, проблема заключается в том, что 'Thread.sleep' ест ваши потоки. В целях тестирования вы также можете попробовать 'akka.pattern.after' создать будущее, которое будет завершено позже, без блокировки потоков. – jrudolph
@Haspemulator Я новичок в мире акков и должен был по-настоящему почесать голову о том, что попало в файл conf, чтобы получить упомянутую производительность для «Для сравнения, вот полные неблокирующие результаты теста на моей машине с пулом потоков fork-join по умолчанию: «Не могли бы вы поделиться тем же. Ваш ответ очень информативен. Cheers – Akash