面临扩展 akka-http 服务器的问题
Facing issue scaling up akka-http server
我有一个 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%)
但是当我从 3 台不同的机器上访问时,每台机器有 200 个线程(总共 600 个线程):我得到以下响应:
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 个线程访问服务器时,客户端的速度也会下降。
我已经把akka.http.server.max-connections
给了8192,而改变akka.http.server.pipelining-limit
对上面的结果没有影响。
将 akka-http 更新为 10.0.11
也没有帮助。
您的 Thread.sleep 使性能变得最差。前段时间,我写了一个 Akka-http 服务器,你可以配置响应的延迟。使用 Futures,向一个参与者发送消息并使用 akka after 模式来避免停止线程 https://github.com/EmiCareOfCell44/http-retarder/blob/master/src/main/scala/io/ecocell44 。看看这个,然后告诉我它是否改进了你的实验。
永远不要将 Thread.sleep
与期货一起使用(至少在没有适当的 ExecutorService 的情况下)
等待使用 Scheduler.scheduleOnce
和 Promise
一起使用(完全未经测试):
get {
parameters('dummy') { dummy =>
complete{
val p = Promise[GenericResponse]()
system.scheduler.scheduleOnce(50 milliseconds) {
p success GenericResponse(200, Map(), Response("Success"))
}
p.future
}
}
}
我有一个 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%)
但是当我从 3 台不同的机器上访问时,每台机器有 200 个线程(总共 600 个线程):我得到以下响应:
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 个线程访问服务器时,客户端的速度也会下降。
我已经把akka.http.server.max-connections
给了8192,而改变akka.http.server.pipelining-limit
对上面的结果没有影响。
将 akka-http 更新为 10.0.11
也没有帮助。
您的 Thread.sleep 使性能变得最差。前段时间,我写了一个 Akka-http 服务器,你可以配置响应的延迟。使用 Futures,向一个参与者发送消息并使用 akka after 模式来避免停止线程 https://github.com/EmiCareOfCell44/http-retarder/blob/master/src/main/scala/io/ecocell44 。看看这个,然后告诉我它是否改进了你的实验。
永远不要将 Thread.sleep
与期货一起使用(至少在没有适当的 ExecutorService 的情况下)
等待使用 Scheduler.scheduleOnce
和 Promise
一起使用(完全未经测试):
get {
parameters('dummy') { dummy =>
complete{
val p = Promise[GenericResponse]()
system.scheduler.scheduleOnce(50 milliseconds) {
p success GenericResponse(200, Map(), Response("Success"))
}
p.future
}
}
}