Scala 扩展akka http服务器面临的问题

Scala 扩展akka http服务器面临的问题,scala,akka,akka-http,Scala,Akka,Akka Http,我有一个sbt项目:版本: Versions of akka-actor, akka-stream = 2.4.17 Versions of akka-http-core and akka-http = 10.0.4 以下是我启动服务器的方式: system = ActorSystem("my-server", conf) mat = ActorMaterializer.create(system) ec = system.dispatcher httpService = Http().bi

我有一个sbt项目:版本:

Versions of akka-actor, akka-stream = 2.4.17
Versions of akka-http-core and akka-http = 10.0.4
以下是我启动服务器的方式:

system = ActorSystem("my-server", conf)
mat = ActorMaterializer.create(system)
ec = system.dispatcher

httpService = Http().bindAndHandle(routeWithTypeAndLogging(routeType), bindHost, bindPort)
我已经编写了一个API,它的睡眠时间只有30到60毫秒,我在
jmeter
中点击它来了解:在客户端不面临更高吞吐量的情况下,我可以点击API的并发性有多大。API部署在一台20核、34G的机器上。API如下所示:

get {
  parameters('dummy') { dummy =>
  complete{
    Future {
    Thread.sleep(30 + randomGenerator.nextInt(30))
    GenericResponse(200, Map(), Response("Success"))
  }(ioDispatcher)
  }
  }
}
当我使用jmeter中的200个线程访问此API时:我得到以下响应:

summary +  88512 in 00:00:25 = 3522.2/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary =  88513 in 00:00:25 = 3485.3/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary + 106546 in 00:00:30 = 3551.5/s Avg:    55 Min:    30 Max:   904 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 195059 in 00:00:55 = 3521.2/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary + 106825 in 00:00:30 = 3560.8/s Avg:    55 Min:    30 Max:  1127 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 301884 in 00:01:25 = 3535.1/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary =  98338 in 00:01:22 = 1203.3/s Avg:   163 Min:    30 Max: 10022 Err:    70 (0.07%)
summary +  35672 in 00:00:30 = 1189.1/s Avg:   162 Min:    30 Max:  7944 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 134010 in 00:01:52 = 1199.5/s Avg:   163 Min:    30 Max: 10022 Err:    70 (0.05%)
summary +  35837 in 00:00:30 = 1194.6/s Avg:   173 Min:    30 Max:  9140 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 169847 in 00:02:22 = 1198.5/s Avg:   165 Min:    30 Max: 10022 Err:    70 (0.04%)
summary +  35024 in 00:00:30 = 1167.5/s Avg:   164 Min:    30 Max: 10040 Err:    69 (0.20%) Active: 200 Started: 200 Finished: 0
summary = 204871 in 00:02:52 = 1193.1/s Avg:   165 Min:    30 Max: 10040 Err:   139 (0.07%)
但当我从3台不同的机器上点击,每台机器有200个线程(总共600个线程):我得到以下响应:

summary +  88512 in 00:00:25 = 3522.2/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary =  88513 in 00:00:25 = 3485.3/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary + 106546 in 00:00:30 = 3551.5/s Avg:    55 Min:    30 Max:   904 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 195059 in 00:00:55 = 3521.2/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary + 106825 in 00:00:30 = 3560.8/s Avg:    55 Min:    30 Max:  1127 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 301884 in 00:01:25 = 3535.1/s Avg:    55 Min:    30 Max:  1547 Err:     0 (0.00%)
summary =  98338 in 00:01:22 = 1203.3/s Avg:   163 Min:    30 Max: 10022 Err:    70 (0.07%)
summary +  35672 in 00:00:30 = 1189.1/s Avg:   162 Min:    30 Max:  7944 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 134010 in 00:01:52 = 1199.5/s Avg:   163 Min:    30 Max: 10022 Err:    70 (0.05%)
summary +  35837 in 00:00:30 = 1194.6/s Avg:   173 Min:    30 Max:  9140 Err:     0 (0.00%) Active: 200 Started: 200 Finished: 0
summary = 169847 in 00:02:22 = 1198.5/s Avg:   165 Min:    30 Max: 10022 Err:    70 (0.04%)
summary +  35024 in 00:00:30 = 1167.5/s Avg:   164 Min:    30 Max: 10040 Err:    69 (0.20%) Active: 200 Started: 200 Finished: 0
summary = 204871 in 00:02:52 = 1193.1/s Avg:   165 Min:    30 Max: 10040 Err:   139 (0.07%)
正如您所看到的,在这两种情况下,我都无法获得超过3600qps的性能,但令人担忧的是,600个线程命中了服务器,这也降低了客户端的性能

我已经向8192提供了
akka.http.server.max连接,而更改
akka.http.server.pipeline限制
对上述结果没有影响


将akka http更新到
10.0.11
也没有帮助。

您的Thread.sleep使性能变得最差。很久以前,我编写了一个Akka http服务器,您可以配置响应的延迟。使用Futures,向一个参与者发送消息,并使用akkaafter模式来避免停止线程。看看这个,你告诉我它是否改善了你的实验。

你的线程。睡眠使性能变得最差。很久以前,我编写了一个Akka http服务器,您可以配置响应的延迟。使用Futures,向一个参与者发送消息,并使用akkaafter模式来避免停止线程。看看这个,你告诉我它是否改善了你的实验。

永远不要使用
线程。睡眠
与未来(至少在没有适当的执行器服务的情况下)

要等待,请使用
Scheduler.scheduleOnce
Promise
类似(完全未经测试)一起使用:


永远不要将
Thread.sleep
与未来一起使用(至少在没有适当的Executor服务的情况下)

要等待,请使用
Scheduler.scheduleOnce
Promise
类似(完全未经测试)一起使用:


你能解释一下为什么线程、睡眠和未来不能很好地结合在一起吗。在我的实际代码中,会有类似DB/kafka等的I/O调用,所以我只是尝试通过Thread.sleep模拟这些I/O调用。还将使用调度器对其进行测试,但bot非常确定哪种方式更适合模拟I/O。Futures围绕使用小线程池的fork-join工作。如果您阻塞了一个线程,那么在最好的情况下,fork-join框架将为您创建更多线程,这在运行时非常昂贵(最坏的情况是线程池不足问题)。此外,如果您阻塞了,那么您就失去了异步方法的整个使用点(线程数越少=上下文切换越少,这是非常昂贵的)。如果您使用异步驱动程序,使用I/O是没有问题的,Kafka和许多数据库都有异步驱动程序。如果您确实需要阻止,则需要更改调度程序:但我建议您更改技术。感谢使用调度程序,我能够获得约15k qps,性能更好,我会看看我的实际代码,看看你提到的优化方法。你能解释一下为什么Thread.sleep和Future不能很好地结合在一起吗。在我的实际代码中,会有类似DB/kafka等的I/O调用,所以我只是尝试通过Thread.sleep模拟这些I/O调用。还将使用调度器对其进行测试,但bot非常确定哪种方式更适合模拟I/O。Futures围绕使用小线程池的fork-join工作。如果您阻塞了一个线程,那么在最好的情况下,fork-join框架将为您创建更多线程,这在运行时非常昂贵(最坏的情况是线程池不足问题)。此外,如果您阻塞了,那么您就失去了异步方法的整个使用点(线程数越少=上下文切换越少,这是非常昂贵的)。如果您使用异步驱动程序,使用I/O是没有问题的,Kafka和许多数据库都有异步驱动程序。如果您确实需要阻止,则需要更改调度程序:但我建议您更改技术。感谢使用调度程序,我能够获得约15k qps,性能更好,我会看看我的实际代码,看看可以做什么优化,正如你提到的。