网络方面一些经验
网络协议里关于流量控制、提高交互效率、提高稳定性的部分,个人认为是最难的部分,以致于在LINUX内核里相关的实现都有BUG。前些年在追查一些网络故障的时候,看了些文档,一直想写些总结文章,但是这方面的内容实在太零散了,相关的RFC文档都好几个,把这些内容都说一遍,基本就把TCP/IP协议说了一遍。就只能挑几个CASE说了
1、连接耗尽,这一般是短连接造成的。解决方案是,用长连接。这个方法看起来简单,其实很难,长连接会碰到更多各种各样的委琐事,不考虑性能的情况,还是用短连接简单。不过一般的公司都会有抽象出来的连接池一类,可以解决这个问题。用起来简单,只是追查问题的时候不知道从哪入手。
当然也有委琐一点的解决方案,比如ulimit,或者,如果是A向B请求数据,B返回数据,然后双方关连接的交互模式,要求B先关连接,至于为什么这样做,我也解决不清楚,可以查一下timewait的说明。
2、交互延迟,或者丢包(这可能也是延迟造成的,超时后不等待了,在上层看来就是丢包)。这个问题非常复杂,有各种杂七杂八的可能。常见于长连接。首先一种可能是,有的算法是,要求一次凑够多少数据才发送。这主要是因为,每发送一个包都要附加很多描述,比如包的长度、IP等,如果一次只发一点数据会很浪费,所以会凑。在强调时效性的场合,最简单解决的方法是直接关闭这一算法,但是LINUX的实现有BUG,要小心。还有一种可能是,发送方为了避免重发太多包,会在等到接收方返回ACK之后,再发送新的包,如果等不到,则重发旧的包,而接收方为了节省ACK的开销,会把几个ACK凑在一起,或者附在别的数据包上一起发回去,这样可能会导致ACK迟迟不来,然后发送方一直在等。最简单的做法是,在应用层把一次交互需要的包合成一个大包,一次发送,但是如果包实在太大了,还是会分多次发送的,不能治本。把多个小包凑成一个大包,表面上看是一件很简单的事情,实践中却是很艰难。这种模块间的交互,很可能是不同的项目组在做,别人才不管这边的延迟、KPI啥的,这件事情做了大半年才做完。还有别的可能,一时没想起来
3、带宽过小,带宽过小的原因非常多,这里就不一一讨论了。首先一点是,在系统出现问题的时候,要识别出是带宽的问题,而不是模块本身性能问题。一般的做法是,执行一下scp之类的操作看一下带宽能到多少。在专用光纤的情况下,如果带宽还是很小,很可能是因为延迟太大了。TCP会要求,在接收到ACK之前,至多发K个包,在延迟非常大的情况下,发一次ACK就要20MS(可以PING一下),这时候一秒至多就能发50K个包了,所以解决的方案是把K增大。K也不能无限增大,因为K太大,一旦出错,需要重传的包会很多,考虑网络情况,适当取舍。很多时候光增大K是不够的,一般的模块,会有一个机制,需要知道下游的模块是否在处理自己的数据(有可能机器收到了,但是处理模块挂了),这需要下游模块显式地发送一个应答,这也会导致延迟,还需要相应地调整响应机制。所以用通用的消息队列传输数据会比较好,不需要每个模块都考虑这个问题。
4、交互双方对交互成功、失败的结果不一致。比如A向B发数据,A显示写成功,而B显示读失败。这一般是因为写操作,只是把数据从模块的BUFFER写到操作系统的BUFFER
建议继续学习:
- 系统架构的一些思考 (阅读:5591)
- 记一次丢包网络故障 (阅读:5312)
- qperf测量网络带宽和延迟 (阅读:4570)
- 网络丢包率如何解决 (阅读:4070)
- 限制单个进程的带宽 (阅读:3653)
- 在 Linux 的应用中测试中的延时和丢包模拟 (阅读:3468)
- 时延和带宽的关系 (阅读:3398)
- 一些队列理论 吞吐量、延迟和带宽 (阅读:3253)
- Velocity:TCP与低带宽网络的性能【译】 (阅读:3145)
- dropwatch 网络协议栈丢包检查利器 (阅读:2318)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:杨镇锋 来源: 我思故我在
- 标签: 丢包 交互延迟 带宽 短连接
- 发布时间:2011-01-12 23:18:19
- [66] Go Reflect 性能
- [66] Oracle MTS模式下 进程地址与会话信
- [65] 如何拿下简短的域名
- [59] IOS安全–浅谈关于IOS加固的几种方法
- [59] android 开发入门
- [59] 图书馆的世界纪录
- [58] 【社会化设计】自我(self)部分――欢迎区
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 界面设计速成
- [47] 读书笔记-壹百度:百度十年千倍的29条法则