scala TIME_WAIT 连接过多,出现“无法分配请求的地址”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26019164/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Too many TIME_WAIT connections, getting "Cannot assign requested address"
提问by jcm
I have a small web application which opens a TCP socket connection, issues a command, reads the response and then closes the connection for every request to a particular REST endpoint.
我有一个小型 Web 应用程序,它打开 TCP 套接字连接,发出命令,读取响应,然后关闭对特定 REST 端点的每个请求的连接。
I've started load testing the endpoint using Apache JMeter and am noticing that after running for some time, I start seeing errors like "Cannot assign requested address", the code opening this connection is:
我已经开始使用 Apache JMeter 对端点进行负载测试,并注意到在运行一段时间后,我开始看到诸如“无法分配请求的地址”之类的错误,打开此连接的代码是:
def lookup(word: String): Option[String] = {
try {
val socket = new Socket(InetAddress.getByName("localhost"), 2222)
val out = new PrintStream(socket.getOutputStream)
val reader = new BufferedReader(new InputStreamReader(socket.getInputStream, "utf8"))
out.println("lookup " + word)
out.flush()
var curr = reader.readLine()
var response = ""
while (!curr.contains("SUCC") && !curr.contains("FAIL")) {
response += curr + "\n"
curr = reader.readLine()
}
socket.close()
curr match {
case code if code.contains(SUCCESS_CODE) => {
Some(response)
}
case _ => None
}
}
catch {
case e: Exception => println("Got an exception "+ e.getMessage); None
}
}
When I run netstat I also see a lot of the following TIME_WAIT connection statues, which implies to me that I am running out of ports in the ephemeral space.
当我运行 netstat 时,我还会看到许多以下 TIME_WAIT 连接状态,这对我来说意味着我在临时空间中的端口用完了。
tcp6 0 0 localhost:54646 localhost:2222 TIME_WAIT
tcp6 0 0 localhost:54638 localhost:2222 TIME_WAIT
tcp6 0 0 localhost:54790 localhost:2222 TIME_WAIT
tcp6 0 0 localhost:54882 localhost:2222 TIME_WAIT
I am wondering what the best solution is for this issue. My current thought is that creating a connection pool where connections to this service running on port 2222can be reused by different HTTP requests, rather than creating new requests each time. Is this a sensible way of fixing the issue and making the application scale better? It seems like a lot of overhead to introduce and definitely makes my application more complicated.
我想知道这个问题的最佳解决方案是什么。我目前的想法是创建一个连接池,其中运行在端口上的此服务的连接2222可以被不同的 HTTP 请求重用,而不是每次都创建新的请求。这是解决问题并使应用程序更好地扩展的明智方法吗?引入似乎有很多开销,并且肯定会使我的应用程序更加复杂。
Are there any other solutions for helping this application scale and overcome this port issue that I'm not seeing? My web application is running in an Ubuntu linux VM.
是否有任何其他解决方案可以帮助此应用程序扩展并克服这个我没有看到的端口问题?我的 Web 应用程序在 Ubuntu linux VM 中运行。
回答by abacabadabacaba
Yes, creating a connection pool is a good solution. However, an easier solution is to have the server close connections, rather than the client. In this case, the server's sockets, rather than the client's, would end up in TIME_WAIT state, so the client would not run out of ports. On the server side, connections in TIME_WAIT state would not make the server run out of ports because they all use the same local port.
是的,创建连接池是一个很好的解决方案。但是,更简单的解决方案是让服务器关闭连接,而不是客户端。在这种情况下,服务器的套接字而不是客户端的套接字将最终处于 TIME_WAIT 状态,因此客户端不会用完端口。在服务器端,处于 TIME_WAIT 状态的连接不会使服务器耗尽端口,因为它们都使用相同的本地端口。
To make sure that the connection is closed by the server, you need to read from the socket (on the client) until you reach end-of-file condition. At this moment, it is safe to close the socket on the client side because the server has closed it already. Of course, you need to make sure that the server would close the socket, rather than, say, waiting for a new request.
为了确保服务器关闭连接,您需要从套接字(在客户端上)读取,直到达到文件结束条件。此时,在客户端关闭套接字是安全的,因为服务器已经关闭了它。当然,您需要确保服务器关闭套接字,而不是等待新的请求。
Alternatively, if you have root access, there are some sysctloptions that you can tweak:
或者,如果您具有 root 访问权限,则可以调整一些sysctl选项:
net.ipv4.ip_local_port_range– range of ephemeral ports. Increase it to make more ports available for outgoing connections.net.ipv4.tcp_tw_recycle– enable faster recycling of connections in TIME_WAIT state.net.ipv4.tcp_tw_reuse– enable reuse of connections in TIME_WAIT state. Not recommended.
net.ipv4.ip_local_port_range– 一系列临时端口。增加它以使更多端口可用于传出连接。net.ipv4.tcp_tw_recycle– 在 TIME_WAIT 状态下启用更快的连接回收。net.ipv4.tcp_tw_reuse– 启用 TIME_WAIT 状态下的连接重用。不建议。
回答by user207421
Connection-pooling will solve this problem for you.
连接池将为您解决这个问题。

