首页 > 代码库 > 《一个 Go 程序系统线程暴涨的问题》结论

《一个 Go 程序系统线程暴涨的问题》结论

作者的结论没写好,我来说两句。。

 

结论:
Docker swarm自己有个函数,叫setTcpUserTimeout,这个函数调用了conn.File()方法,将tcp的fd变成了blocking,而且没有关闭对应的fd。相当于每次设定tcpUserTimeout参数,再去read一下fd,都会产生一个新的线程。因为老的线程在读fd,而fd被设置成blocking了,于是golang的运行时只好再开一个新的。
解决方法:
不要用swarm的这个方法,或者提交到上游让swarm fixed掉,或者自己调用SetsockoptInt……
 
好奇八卦了一下TCP_USER_TIMEOUT是什么:根据RFC 5482,这个选项是用来跟对端沟通TCP超时时间的。顺带看了一下,有关TCP超时的RFC还包括:[RFC0793]  [RFC1122]。之前,TCP有类似的超时选项TCP Keepalive。但是,TCP Keepalive是一个不建议打开的选项。因为委员会觉得这样会浪费带宽,引起不必要的网络中断。说白了,TCP是一组计时器组成的状态机,设计者是希望中间的电路中断、重新路由之类的变动,不会影响到两端的TCP状态。
 
待续
 
 

《一个 Go 程序系统线程暴涨的问题》结论