- 论坛徽章:
- 9
|
本帖最后由 wlmqgzm 于 2015-10-23 09:38 编辑
漫谈针对"socket_handle复用"的 高可靠性解决方案.
在做网络服务器时, 不可避免的遇到操作系统底层复用socket_handle带来的问题, 就是高层软件还在处理某个socket_handle=10的连接各类故障或者各类超时等待中, TCP/IP底层其实已经拆线了, 并且有新连接进来, 该socket_handle=10又被赋值给了新的连接, 并且由于并发处理, 新的socket_handle=10可能已经开始收发处理数据了, 老的socket_handle=10还在走拆线流程, 造成冲突.
危害就是某个连接可能出现其他数据冲突, 甚至莫名其妙的异常中断, 丢失数据包.
目前代码的解决方案是:
在前面所有管理数据单线程运行的前提下,
给每个socket_handle操作全部携带上时间指纹 accept_time(微秒级别),
新连接进来时将存储管理数据,
在存储数据时检查socket_handle, accept_time, 使用最新数据覆盖老数据
在执行一切操作时检查对比存储数据的socket_handle, accept_time, 当指令中携带的时间指纹与存储数据中不一致时, 避免操作, 直接丢弃过时的操作指令.
总之, 一切socket操作都有检查和校验, 可以解决此问题.
我的优势就在于单线程管理后台所有数据, 可以很简单的高性能高可靠的解决此问题.
目前, 民用级别的网络服务器软件, 多数都是忽略此问题, 可能认为发生的小概率, 或者故意漠视, 认为偶然断开一个新连进来的连接, 或者丢一个新连接的新数据包, 认为不是问题.
那么, 高可靠性网络服务器软件在设计上, 必须要避免此类问题的发生.
说一个笑话:
三个程序员被要求穿过一片田地,到达另一侧的房子。
菜鸟程序员目测了一下之间很短的距离,说:“不远!我只要十分钟。”
资深程序员看了一眼田地,想了一会,说:“我应该能在一天内过去。”菜鸟程序员很惊讶。
大神程序员看了一眼田地,说:“看起来要十分钟,但我觉得十五分钟应该够了。” 资深程序员冷笑了一声。
菜鸟程序员出发了,但只过了一会,地雷爆炸了,炸出了巨大的洞。这下他必须偏移预定的路线,原路返回,反复尝试穿过田地。最后他花了两天到达目的地,到的时候颤颤发抖,还受了伤。
资深程序员一出发就匍匐前进,仔细地拍打地面,寻找地雷,只有在安全的时候才前进。他在一天的时间内小心谨慎地缓慢爬过了这片地,只触发了几个地雷。
大神程序员出发之后径直穿过了田地,十分果断。他只用了十分钟就到了另一边。
“你是怎么做到的?”另外两个人问道,“那些地雷怎么没有伤到你?”
“很简单,”他回答道,“我最初就没有埋地雷。” |
|