HI,ALL: 最近在用net的TCP SOCKET来做一个网关中转服务器,面临的场景是:大量的TCP长连接,频繁的数据交互(每个链接没秒10个包,至少需要维持5000链接)。 由于我的数据都是自定义格式的二进制流,所以收发数据全部BUFFER结构。 同时,为了尽可能减少BUFFER的申请,我自己做了一个BUFFER的缓冲池POOL,内部全部是定长的Slow BUFFER,每次发送数据的时候,从POOL内取一个BUFFER,放入数据,然后交个write方法,等待发送完成之后,在回收回POOL。类似代码如下: // 发送消息(主要是逻辑层的消息数据)
- SendData:function(data)
- {
- // 发送数据
- var len = data.length;
- var node = MemoryManager.GetNode(len+4);
- // 写入数据
- …
- // 发送
- this.mSocket.write(node.slice(0, len), function()
- {
-
MemoryManager.ReleaseNode(node);
- });
- },
经过大量的测试(尤其是模拟用户链接会出现各种异常断线,关闭SOCKET等情况): 1:发现我每次write申请的BUFFER个数和write结束后回调里面回收的BUFFER个数对不上,如果当前链接一旦出现异常断开后,很多以发起write的操作不会callback,导致了内存泄露(不知道是不是BUG??) 现在遇到了大量的内存泄露问题,且没有办法很好的解决,大家有更好的方案吗?
待会会有 aliyun 的人来让你用 alinode … 手动 dog
请使用alinode,分分钟告诉你哪里出问题了 From Noder
callback 不触发,就是出错,看你是否监听error事件,或者设置timeout针对异常连接
谢谢大家的回复,昨晚经过大量的测试证明:、 1:SOCKET的write callback仅仅在数据发送成功才会回调,如果存在大量的write请求,SOCKET一旦出错,后面的就不会再触发callback. 2:现在的做法是每次发起write的时候,把对应的BUFFER都存在一个队列里面,然后callback的时候,从队列弹出第一个BUFFER,然后回收(因为TCP的有序的,我们发送的所有数据也都会有序的触发callback,所以顺序没问题;一旦出错,就把队列里面剩余的BUFFER回收)
这部分其实是个大坑,如果用SOCKET读写大量BUFFER的话,一定要注意