How to handle a lot of CLOSE_WAIT TCP connections?

agolangf · · 824 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have 2 TCP servers, one is acting as a client to the other. Let&#39;s say A is client and B is server.</p> <p>Every 30-60 seconds, A opens TCP connection, check the error, and close it immediately (basically a form of health check).</p> <p>After many hours, there are a lot of CLOSE_WAIT TCP connections on server A.</p> <p>What can I do on server B to acknowledge these CLOSE_WAIT connections and clean them up properly?</p> <p><strong>EDIT</strong></p> <p>The client code uses this library: <a href="https://github.com/tevino/tcp-shaker" rel="nofollow">https://github.com/tevino/tcp-shaker</a> because it skips the final ACK on Linux. I basically do the following:</p> <pre><code>// Client Code import &#34;time&#34; import &#34;github.com/tevino/tcp-shaker&#34; c := tcp.NewChecker(true) c.InitChecker() for { err := c.CheckAddr(&#34;serverB:8080&#34;, 2 * time.Second) if err != nil { // do something with the error. println(err.Error()) } time.Sleep(30*time.Second) } </code></pre> <p>The server-side code looks very much like this repo: <a href="https://github.com/firstrow/tcp_server" rel="nofollow">https://github.com/firstrow/tcp_server</a>.</p> <pre><code>// Server Code import &#34;bufio&#34; import &#34;net&#34; listener, err := net.Listen(&#34;tcp&#34;, &#34;serverB:8080&#34;) if err != nil { println(err.Error()) return } defer listener.Close() for { conn, err := listener.Accept() if err != nil { if conn != nil { conn.Close() } time.Sleep(time.Second) continue } conn.SetWriteDeadline(time.Now().Add(5*time.Second)) defer conn.Close() go func(conn net.Conn) { reader := bufio.NewReader(conn) for { message, err := reader.ReadString(&#39;\n&#39;) if err != nil { conn.Close() break } println(message) // Do something with the message. } }(conn) } </code></pre> <p><strong>ONE SMALL NOTE</strong></p> <p>The actual server is listening on TLS (and I have verified that it works), I just don&#39;t want to open TLS connection for simple health checking. </p> <hr/>**评论:**<br/><br/>wheey: <pre><p>CLOSE_WAIT is due to the fact, as you mentioned, that client sent a FIN and system has initiated closing a connection. A is now waiting for B to close a connection and thus sends an ACK to the A which then closes a connection.</p> <p>Problem here is either that B is not closing a connection or it does not listen for one.</p> <p>If you could share a code A&lt;-&gt;B maybe we can be more precise. </p></pre>pinpinbo: <pre><p>I have updated my post with a simplified code example. The error checking location is exactly where I put it on my actual code.</p></pre>i_regret_most_of_it: <pre><p>Hard to say without seeing the client code. Are you fully reading the response body? Are you sure you are always closing the connection? Are you re-using the http client?</p></pre>pinpinbo: <pre><p>Yes, the TCP library that I use always calls <code>Close()</code>. In this case I am not reusing the TCP connections.</p> <p>I have updated my post with a simplified code example. The error checking location is exactly where I put it on my actual code.</p></pre>niosop: <pre><p>Try it without tcp-shaker? Might as well do a full TLS connection as well. One TLS setup/teardown every 30 seconds isn&#39;t going to hurt anything.</p></pre>wheey: <pre><p>There is probably some kind of lock when you are calling close. But, what I would suggest is putting goroutine in separate function and then on error rather call return then break; PS. I had a problem before with SetWriteDeadline and sometimes it happened that it would never close connection.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

824 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传