GithubHelp home page GithubHelp logo

持续读会撑爆内存 about zltoolkit HOT 8 CLOSED

huyuguang avatar huyuguang commented on August 17, 2024
持续读会撑爆内存

from zltoolkit.

Comments (8)

xia-chu avatar xia-chu commented on August 17, 2024

你说的这个问题确实存在,因为Tcp会话处理逻辑其实是在后台线程池里面完成的,而网络数据流的接收是在主线程(网络事件线程)完成。如果TcpSession数据处理迟滞,那么会导致其绑定的线程池任务暴涨,间接导致内存暴涨。要解决这个问题在库里面实现不太现实,因为库底层只能监测到哪条线程池任务暴涨,但是不能确定是哪个Socket导致的。
但是可以通过添加业务逻辑代码来实现,在你的TcpSession里面,你需要把阻塞式的操作放在后台线程里面操作,如果后台线程任务繁忙那么你可以通过调用 Socket::enableRecv(false)来停止接收数据,这时会触发如你所说的“tcp协议栈会降低tcp wnd“;当你的后台线程任务空闲了你可以通过调用 Socket::enableRecv(true)来恢复网络数据的接收。
总之,不建议你在TcpSession里面直接执行阻塞式任务。

from zltoolkit.

huyuguang avatar huyuguang commented on August 17, 2024

这个问题并不一定因为tcpsession里执行阻塞任务导致。前面举的例子是file write,这个的确是个阻塞操作,另外有些情况也会导致,比如假设是一个proxy,server->proxy发来的数据非常快,proxy->client速度很慢,那么同样可能因为上下行速度不一致导致内存撑爆。

我看到enableRecv了,这个API的确可以实现这个逻辑,但是你好像只处理了edge模式,并没有处理level模式?我觉得不处理level模式也没什么,只不过level模式的代码为何不干脆去掉呢?

from zltoolkit.

xia-chu avatar xia-chu commented on August 17, 2024

你说的那个问题其实不存在。 如果toolkit往客户端发数据,由于网络原因
导致数据发不出去,那么toolkit将会清空发送缓冲区,所以就会导致发送端的主动丢包。

还有水平触发移除事件监听是很容易做到的,但是考虑到线程安全和库的稳定性,我并没有贸然加入这个特性;毕竟接受数据处理不过来这种情形一般发生在服务端,而服务端一般是linux系统,linux平台默认采用边沿触发方式,不存在事件一直触发的问题。其他平台采用select水平触发方式才会出现如你所说性能问题,但是其他平台下toolkit是定位于客户端开发,对性能本身不是很敏感,况且停止接收数据后才会存在一直触发的问题,而这种场景其实在客户端程序并不多见。
如果对这个特性真得有需求,那么修改源码也是很容易达成这个目的,但是是否会引入其他不可预知的问题还需要自己考量。

from zltoolkit.

huyuguang avatar huyuguang commented on August 17, 2024

"如果toolkit往客户端发数据,由于网络原因
导致数据发不出去,那么toolkit将会清空发送缓冲区,所以就会导致发送端的主动丢包。" 主动丢包比直接断连接还糟糕。
网络编程,客户端和服务端根本没有什么区别。

from zltoolkit.

xia-chu avatar xia-chu commented on August 17, 2024

�首先,socket写缓冲区溢出导致主动丢包的设计是通行的做法,这个也没什么辩驳的。ZLToolKit提供了onFlush接口,可以在socket可写时回调。要实现发送速率的控制并不是难事,比如说你可以使用ZLToolKit实现一个文件HTTP服务器,通过发送速率来控制文件读取速率(事实上我也有这方面的相关实现,你可以查看我另外一个项目:ZLMediaKit)。还有,主动丢包这样的应用场景很多,有些丢包是允许的;比如说你用OBS推流到rtmp服务器,同时又用播放器播放该直播,假设说播放器端网速不够,那个服务器不可能一直缓存下去,rtmp服务器也不可能限制obs推流端速率(因为这个流可能也会被其他用户播放);那么结果就只有服务器端的主动丢包。

还有,我需要指出的是,ZLToolKit的特点是轻量,不可能做到面面俱到;所以ZLToolKit比较适合在linux(epoll实现)平台下做规模比较大的服务器,而在其他平台(select实现)只比较适合做客户端和小负荷服务器。在停止接收时,水平触发导致的效率问题在非linux平台下确实会有,但是这并不是一个很迫切的任务,后续在我经过验证的情况下可能会加入移除水平监听的特性。

有什么问题你也可以加入QQ群(542509000)一起探讨,欢迎各种建议和提问,感谢你在此的讨论!

from zltoolkit.

huyuguang avatar huyuguang commented on August 17, 2024

主动丢包的场合都是在应用层,比如视频流之类。不可能在网络库里主动丢包的。

from zltoolkit.

dongwenjia avatar dongwenjia commented on August 17, 2024

是否主动丢包,要看具体的项目情况,这个可以在应用层进行实现

from zltoolkit.

xia-chu avatar xia-chu commented on August 17, 2024

ZLToolKit已经添加接口可以设置是否由底层网络框架主动丢包;默认主动丢包

from zltoolkit.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.