Акка http выдает исключение на высокой пропускной способности - java.io.IOException: слишком много открытых файлов в системе
Я пытаюсь отправить 200k сообщений на akka-http .
protected val someRouts: Route = pathPrefix("foo") {
pathEndOrSingleSlash {
put {
entity(as[Foo]) { foo =>
log.debug(s"/foo update $foo")
complete(Future(Foo("a")).map(f => s"Got - $f "))
}
}
}
Http().bindAndHandle(someRouts, "0.0.0.0", 9000)
из другого процесса я отправляю в цикле 200К сообщений. код клиента (упрощенно):
lazy val apiFlow: Flow[HttpRequest, HttpResponse, Any] =
Http().outgoingConnection("0.0.0.0", 9000)
def request(request: HttpRequest): Future[HttpResponse] = Source.single(request).via(apiConnectionFlow).runWith(Sink.head)
for (i <- 1 to 200000){
request(RequestBuilding.Put("/foo", Foo(i))
}
через некоторое время я получаю это исключение:
[akka.actor.default-dispatcher-33] ERROR akka.io.TcpListener - Accept error: could not accept new connection
java.io.IOException: Too many open files in system
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
at akka.io.TcpListener.acceptAllPending(TcpListener.scala:112)
at akka.io.TcpListener$$anonfun$bound$1.applyOrElse(TcpListener.scala:85)
at akka.actor.Actor$class.aroundReceive(Actor.scala:502)
at akka.io.TcpListener.aroundReceive(TcpListener.scala:34)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
ОБНОВЛЕНИЕ проверка открытых соединений с помощью lsof -i tcp:9000 | wc -l
Я вижу, что число значительно выше 6500
1 ответ
Ваша проблема в том, что вы пытаетесь открыть 200 000 TCP-подключений к 0.0.0.0:9000
и компьютер, с которым вы работаете, не настроен на одновременное использование большого количества файловых дескрипторов.
Из документов (выделение мое):
Обратите внимание, что соединение не предпринимается, пока возвращаемый поток не будет материализован! Если поток материализуется несколько раз, то будет открыто несколько независимых соединений (по одному на материализацию).
Проверьте ulimit -n
- это, вероятно, значительно ниже 200К.
Смотрите также: