我有一个在服务器X中运行的喷雾http客户端,它将连接到服务器Y.服务器Y有点慢(请求需要3秒以上)
这是我的http客户端代码调用:
def get() {
val result = for {
response <- IO(Http).ask(HttpRequest(GET,Uri(getUri(msg)),headers)).mapTo[HttpResponse]
} yield response
result onComplete {
case Success(res) => sendSuccess(res)
case Failure(error) => sendError(res)
}
}
这些是我在application.conf中的配置:
spray.can {
client {
request-timeout = 30s
response-chunk-aggregation-limit = 0
max-connections = 50
warn-on-illegal-headers = off
}
host-connector {
max-connections = 128
idle-timeout = 3s
}
}
现在我试图滥用服务器X并发出大量并发请求(使用ab,n = 1000且c = 100)。
直到900请求它没问题。之后,服务器抛出了很多异常,之后我无法点击服务器。 这些是例外:
[info] [ERROR] [03/28/2015 17:33:13.276] [squbs-akka.actor.default-dispatcher-6] [akka:// squbs / system / IO-TCP / selectors / $ a / 0]接受错误:无法接受新连接
[info] java.io.IOException:打开的文件过多 [info] at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) [info] at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:241) [info] at akka.io.TcpListener.acceptAllPending(TcpListener.scala:103)
并且在进一步点击同一台服务器时,它抛出了以下异常:
[info] [ERROR] [03/28/2015 17:53:16.735] [hcp-client-akka.actor.default-dispatcher-6] [akka:// hcp-client / system / IO-TCP / selectors] null [info] akka.actor.ActorInitializationException:创建期间的异常
[info] at akka.actor.ActorInitializationException $ .apply(Actor.scala:164)
[info] at akka.actor.ActorCell.create(ActorCell.scala:596)
[info]引起:java.lang.reflect.InvocationTargetException
[info] at sun.reflect.GeneratedConstructorAccessor59.newInstance(Unknown Source)
[info]引起:java.io.IOException:打开的文件太多 [info] at sun.nio.ch.IOUtil.makePipe(Native Method)
我之前使用的是apache http客户端(它是同步的),能够处理10000多个并发为100的请求。
我不确定我错过了什么。任何帮助将不胜感激。
答案 0 :(得分:3)
问题是每次调用get()
方法时,它都会创建一个新的actor,它至少创建一个与远程服务器的连接。此外,你永远不会关闭那个演员,所以每个这样的连接都会离开,直到它超时。
您只需要一个这样的actor来管理您的所有HTTP请求,因此要修复它需要IO(Http)
方法中的get()
并且只调用一次。重新使用返回ActorRef
的所有请求到该服务器。在应用程序关闭时关闭它。
例如:
val system: ActorSystem = ...
val io = IO(Http)(system)
io ! Http.Bind( ...
def get(): Unit = {
...
io.ask ...
// or
io.tell ...
}