我们的服务器上启了一个redis服务端,侦听0.0.0.0的1234端口,同处在本机的另外一个进程会频繁发起到该服务端的短连接,结果导致了两个问题:
1.大量的TIME_WAIT状态的连接;(电脑维护外包)
2.发起连接的进程的CPU占用率接近100%。
这两个结果严重影响了我们网关的性能,在分析具体原因之前,首先做一个提倡,那就是:本机连接本机,首选UNIX域套接字而不是TCP!
首先我们来看看问题1。TIME_WAIT就不多说了,只要任何一端主动断开连接,那么它最终可能将会进入TIME_WAIT状态,具体是否会进入在Linux上取决于几个因素,第一,有没有两端开启timestamps,如果开启了,有没有在服务端开启recycle,如果开启了,那么TIME_WAIT套接字就会迅速消失,也就是说,想让recycle起作用,一定要开启timestamps。如果没有timestamps,那么就会有大量的TIME_WAIT状态的套接字。
在Linux内核协议栈的实现中,所有连接本机的数据流,其路由选择最终都会到定向到loopback,如果没有绑定源IP地址,那么源/目标IP地址均为127.0.0.1!如果服务端口是固定的,那么最终会接受65535-1个连接,减1的原因在于服务端已经bind了服务端口,因此客户端不能再次bind。这是合理的,因为按照四元组唯一性考虑,一个服务只能接受一个特定IP地址的65535个连接或者65534个连接,但是问题是,如果需求巨大,这显然不能满足要求,你要知道,作为服务器而言,它要考虑的是总的最大并发连接数,一台机器上同时发起6万多个连接的可能性并不大,因此TCP在大多数情况下是合理,采用16bit的端口号刚刚好,因为协议头不能太大,否则载荷率就会变小,这显然是网络传输所要求的,然而本机连本机时,并不需要网络传输,你想当然会认为有多少需求就要都要满足,不过TCP并不适合这种场合。(it外包服务公司)
本机连本机,没有网络传输带来的延迟,吞吐限制也仅限于本机资源利用,因此并发10万甚至更多的需求都是合理的,可是TCP并不能满足,原因就在于它只有16bit的端口号,目标端口固定,同时只能有65534个连接。如何解决呢?我们知道127.0.0.0/8都是属于loopback的,我们可以采用不同的源IP地址,如果想这么做,有两个选择,那就是要么客户端bind源IP为127.x.y.z,要么SNAT成127.x.y.z,这样就可以接受海量的连接需求了。但是这并不是最终的解决方案,为什么非要用TCP呢?TCP本来就是为网络传输设计的,它的流控应对不同的主机,拥控应对反复无常的网络,在本机,这些都不是问题,所以本机连本机,最好使用本机套接字,比如UNIX域套接字。
再来看问题2,一个连接本机的TCP数据包最终到达了loopback的xmit发送函数,其中简单的调度了本CPU上的一个软中断处理,然后会在下一次中断结束后调度其执行,这有很大几率是在当前发送进程的上下文中进行的,也就是说,发送进程在其上下文中进行了发送操作,而此时软中断借用了其上下文触发了接收操作,再然后,LOCK的开销就很明显,由于大量的TW套接字的insert和delete,需要频繁LOCK哈希表,这种开销完全记帐到了发送进程的名下,也是不公平的。
注意,Linux内核中,softirq会在两种上下文中执行,一种是硬件中断后的任意上下文中,一种是每CPU一个内核线程的上下文中,后者会记帐给top命令的si百分比,前者则会记帐给任意被中断的进程。(网络外包公司)
艾锑无限是中国领先IT外包服务商,专业为企业提供IT运维外包、电脑维护、网络维护、网络布线、办公设备维护、服务器维护、数据备份恢复、门禁监控、网站建设等多项IT服务外包,服务热线:400-650-7820 联系电话:010-62684652 咨询QQ1548853602 地址:北京市海淀区北京科技会展2号楼16D,用心服务每一天,为企业的发展提升更高的效率,创造更大的价值。
更多的IT外包信息尽在艾锑无限http://www.itbmw.com
相关文章