Tim's Blog about XMPP Jabber, 同时欢迎访问我的另一独立blog: http://timyang.net/
查看文章 |
再谈点对点通讯模块的故障问题
2008-12-14 00:05
上个月曾经提过一个高负荷服务器点对点通讯模块的若干问题,目前这个模块已经基本稳定,其中一些朋友的留言对改进这个模块也很有启发。最近主要考虑了通讯故障的问题并进行了测试。 服务器之间的通讯通常会由于网络原因造成各种故障,如果在一个LAN之内,出现故障的概率很小,几乎可以不用考虑。但如果分布在不同的地点比如跨机房跨地域,短时故障的概率就会变大,由于中间线路,路由器等各种设备或者VPN的问题,容易出现短期(比如10-30S左右)对方不可到达的情形。如果每秒系统传递的包有成千上万,那问题就会变得很严重,大量的业务数据投递会发生问题,并且按先后顺序发生以下事件。 ![]() 1. Socket send buffer 未占满期间socket会继续可写, 如果设置了SO_SNDBUF则会使用SO_SNDBUF, 否则使用Linux默认的配置。 # increase TCP max buffer size setable using setsockopt()SO_SNDBUF通常按以下公式设置: BDP = link_bandwidth * RTT远端 BDP = 100MBps * 0.050 sec / 8 = 640KB本地 BDP = 1024MBps * 0.005 sec / 8 = 655KBSocket占满后写socket会block, 或者设置了TCP_NODELAY则不管SOCKET buffer是否占满都会block3. 如果应用写入操作没有队列概念则应用程序会出现异常,所有操作会阻塞。 4. 强壮的应用会对发送数据做应用层的buffer,像Connection Manager/Openfire之间是使用发送 Thread Pool,在对方不可到达的时段内,内存占用会急剧上升。 5. 如果网络层恢复正常,首先是socket buffer中的数据会被发送,然后应用层堆积的数据也随后发送。 6. 如果网络层长时间不可用,有2种方法可以判断,通过达到SO_SNDTIMEO Socket返回错误检测,应用层如果需要更早知道错误,可以调低SO_SNDTIMEO。另外一种检测方法是应用检测发送队列达到上限临界值来做进一步 处理。避免服务器内存溢出造成崩溃。实际环境中需要结合这2种方式一起考虑。 Update: 感兴趣朋友可了解后续文章:多服务器通讯层应该如何设计—一次code review小记 |
最近读者:
