Акка 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К.

Смотрите также:

Другие вопросы по тегам