上周,在功能测试的情况下,我们发现了一个难题。
大家的网络服务器启动了一个redis服务器,监听0.0.0.0的端口号1234,同一台电脑上的另一个进程会经常对这个服务器进行短连接,导致两个问题:
1。很多TIME_WAIT连接。
2。连接过程的CPU消耗接近100%。
这两个结果严重危害了网关ip的特性。在分析实际原因之前,首先要做的是倡导,即本机连接本机,首选UNIX域套接字,而不是TCP!
其实你不需要数据的统计分析,只需要基本的理论分析就可以了。前提是你对Linux核心tcp协议的IP层解决方案及其软中断调度有足够的了解。自然,这很简单。
先讨论问题1。TIME_WAIT很少被提及。如果所有东西都在一端主动断开连接,它很可能会以TIME_WAIT的情况结束。其实最后会不会上
Linux取决于很多因素。第一,两边都开时间戳了吗?如果是的话,有没有在服务器端打开recycle?如果有,那么
TIME_WAIT。如果没有时间戳,那么
将会有许多带有TIME_WAIT的套接字。
在Linux的核心tcp协议的完成中,对所有连接到本地计算机的数据流进行分析,最终的路由器选择会是到环回。如果您没有关联的源IP地址,那么源/整个目的IP地址
就是127.0.0.1!如果服务项目端口号是固定的,那么最终将接受65535-a连接。减1的原因取决于服务器已经绑定了服务项端口号,所以手机客户端无法
再次绑定。之所以有效,是因为根据四元组唯一性,一个服务项只接受65,535个连接或者65,534个带有特殊IP地址的连接,但问题是如果需求巨大
,显然无法满足要求。你要知道,作为一个网络服务器,它必须考虑到高并发连接的总数,以及一台设备上的另外60,000个。所以TCP在大多数
情况下是有效的,选择16位服务器端口是合适的。因为协议头不能很大,否则会降低负载率。这显然是数据传输规定的。未知的是,当这台机器连接到这台机器的时候,并不一定是互联网传输
会丢失,你会主观的认为需要考虑多少要求,但是TCP并不适合这种地方。
本地计算机与本地计算机相连,因此不存在数据传输造成的延迟时间,吞吐量限制也只限于使用本地资源。所以10万甚至很大数量的高并发的要求都是成立的,但是不能考虑TCP,因为它只有一个
16bit的服务器端口,整体目标端口号是固定的,只有65534个连接。怎么解决?我们知道127.0.0.0/8都属于环回,可以选择不同的源IP地址
。如果要那样做,有两个选择,即手机客户端bind的源IP是127.x.y.z,或者SNAT是127.x.y.z,我们可以接受[但这不是最终的解决方案。为什么一定要用TCP?最初,TCP是为数据传输而设计的。它的流量控制方案不同于服务器,可以控制善变的网络
。在本地计算机中,这不是问题。因此,最好应用本地套接字,如UNIX域套接字,将本地计算机连接到本地计算机。
我们再来看问题2。一个连接到本机的TCP数据文件最终达到loopback的xmitpush功能,其中简单的调度这个CPU上的一个软中断解决,然后调度到下一个
中断之后执行。这有非常大的概率是在今天的推送过程前后进行的。换句话说,推送进程在其上下文中执行实际的推送 *** 作,然后软中断使用其上下文打开
来接受实际的 *** 作。然后,LOCK的开销是非常显著的,因为很多TWsocket的插入和删除都要频繁地锁定哈希表,这种开销完全记录在push进程的账上是不合理的。
注意,在Linux内核中,softirq会在两种上下文中实现,一种是硬件配置中断后的随机上下文,另一种是每个CPU一个核心进程的上下文,后者会被记录为top命令的si百分比,前者会被记录为随机中断的进程。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)