我有一台 TCP 服务器,它从一个(且只有一个)客户端获取数据。当该客户端发送数据时,它会与我的服务器建立连接,发送一条(逻辑)消息,然后不再在该连接上发送任何消息。
然后它将建立另一个连接来发送下一条消息。
我的一位同事说,从资源的角度来看,这非常糟糕。他说建立连接需要大量资源并且需要一段时间。他说我需要让这个客户端建立连接,然后只要我们需要通信(或者直到出现错误)就继续使用它。
使用单独连接的好处之一是我可以对它们进行多线程处理并获得更多的吞吐量。我向我的同事提到了这一点,他告诉我,打开大量套接字会杀死服务器。
这是真的吗?或者我可以允许它为每个需要发送的逻辑消息建立单独的连接吗? (请注意,我所说的逻辑消息是指长度可变的 xml 文件。)
I have a TCP server that gets data from one (and only one) client. When this client sends the data, it makes a connection to my server, sends one (logical) message and then does not send any more on that connection.
It will then make another connection to send the next message.
I have a co-worker who says that this is very bad from a resources point of view. He says that making a connection is resource intensive and takes a while. He says that I need to get this client to make a connection and then just keep using it for as long as we need to communicate (or until there is an error).
One benefit of using separate connections is that I can probably multi-thread them and get more throughput on the line. I mentioned this to my co-worker and he told me that having lots of sockets open will kill the server.
Is this true? Or can I just allow it to make a separate connection for each logical message that needs to be sent. (Note that by logical message I mean an xml file that is of variable length.)
发布评论
评论(5)
这完全取决于您打算打开和关闭的连接数量以及您打算打开它们的速率。
除非您特意通过中止连接而不是优雅地关闭连接来避免
TIME_WAIT
状态,否则您将在客户端或服务器上累积处于TIME_WAIT
状态的套接字。对于单个客户来说,这些问题在哪里积累实际上并不重要,因为问题是相同的。如果您使用连接的速率比TIME_WAIT
连接关闭的速率快,那么您最终将无法打开任何新连接,因为您没有留下任何临时端口它们都与处于 TIME_WAIT 状态的套接字一起使用。我在这里更详细地写了这一点: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html
在一般我建议您保留单个连接,并在重置时重新打开它。逻辑可能看起来更复杂一些,但系统的扩展性会更好;您现在可能只有一个客户端,并且连接速率可能使您不会遇到 TIME_WAIT 问题,但这些事实可能在系统的生命周期内不会保持不变...
It depends entirely on the number of connections that you are intending to open and close and the rate at which you intend to open them.
Unless you go out of your way to avoid the
TIME_WAIT
state by aborting the connections rather than closing them gracefully you will accumulate sockets inTIME_WAIT
state on either the client or the server. With a single client it doesn't actually matter where these accumulate as the issue will be the same. If the rate at which you use your connections is faster than the rate at which yourTIME_WAIT
connections close then you will eventually get to a point where you cannot open any new connections because you have no ephemeral ports left as all of them are in use with sockets that are inTIME_WAIT
.I write about this in much more detail here: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html
In general I would suggest that you keep a single connection and simply reopen it if it gets reset. The logic may appear to be a little more complex but the system will scale far better; you may only have one client now and the rate of connections may be such that you do not expect to suffer from
TIME_WAIT
issues but these facts may not stay the same for the life of your system...TCP 连接的启动序列是非常简单的 3 次握手,开销非常低。无需保持持续连接。
另外,拥有许多 TCP 连接不会那么快地杀死你的服务器。现代硬件和操作系统可以处理数百个并发 TCP 连接,除非您担心拒绝服务攻击,这显然超出了这个问题的范围。
The initiation sequence of a TCP connection is a very simple 3 way handshake which has very low overhead. No need to maintain a constant connection.
Also having many TCP connections won't kill your server so fast. modern hardware and operating systems can handle hundreds of concurrect TCP connections, unless you are afraid of Denial of service attacks which are out of the scope of this question obviously.
如果您的服务器只有一个客户端,我无法想象在实践中为每条消息打开一个新的 TCP 套接字会出现任何问题。听起来你的同事喜欢过早优化。
但是,如果您向服务器发送大量消息,则可能会成为问题。但对于一个客户来说,我仍然不会担心。
只需确保在完成后关闭套接字即可。没必要对服务员无礼:)
If your server has only a single client, I can't imagine in practice there'd be any issues with opening a new TCP socket per message. Sounds like your co-worker likes to prematurely optimize.
However, if you're flooding the server with messages, it may become an issue. But still, with a single client, I wouldn't worry about it.
Just make sure you close the socket when you're done with it. No need to be rude to the server :)
除了大家说的,考虑一下UDP。它非常适合不需要响应的小消息,并且在本地网络(而不是互联网)上它实际上是可靠的。
In addition to what everyone said, consider UDP. It's perfect for small messages where no response is expected, and on a local network (as opposed to Internet) it's practically reliable.
从服务器的角度来看,打开大量连接并不是问题。
Web 服务器可以处理多少个套接字连接?
从客户端的角度来看,如果测量表明您需要避免启动连接的时间并且您需要并行性,那么您可以创建一个连接池。多个线程可以重复使用每个连接,并在完成后将它们释放回池中。这确实提高了复杂性,所以再次确保您需要它。您还可以有根据活动缩小和增加池的逻辑 - 在应用程序闲置时保持与服务器的连接过夜是很遗憾的。
From the servers perspective, it not a problem to have a very large number of connections open.
How many socket connections can a web server handle?
From the clients perspective, if measuring shows you need to avoid the time initiate connections and you want parallelism, you could create a connection pool. Multiple threads can re-use each of the connections and release them back into the pool when they're done. That does raise the complexity level so once again, make sure you need it. You could also have logic to shrink and grow the pool based on activity - it would be ashame to hold connections open to the server over night while the app is just sitting their idle.