技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 网络系统 --> 网络方面一些经验

网络方面一些经验

浏览:3037次  出处信息

    网络协议里关于流量控制、提高交互效率、提高稳定性的部分,个人认为是最难的部分,以致于在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

建议继续学习:

  1. 系统架构的一些思考    (阅读:5438)
  2. 记一次丢包网络故障    (阅读:5158)
  3. qperf测量网络带宽和延迟    (阅读:4390)
  4. 网络丢包率如何解决    (阅读:3969)
  5. 限制单个进程的带宽    (阅读:3611)
  6. 在 Linux 的应用中测试中的延时和丢包模拟    (阅读:3322)
  7. 时延和带宽的关系    (阅读:3276)
  8. 一些队列理论 吞吐量、延迟和带宽    (阅读:3202)
  9. Velocity:TCP与低带宽网络的性能【译】    (阅读:2997)
  10. dropwatch 网络协议栈丢包检查利器    (阅读:2275)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1