浅谈一个好的网络库设计

       业界比较有名气一点的开源网络库有两个,一个muduo,一个lievent。

       其实但就设计一个网络库而言,难就难在通用,各种业务通用,这个恰好契合业务就不好说,每个人技术栈不同,需求不同,视野不同,就不好说了。总的来说muduo,lievent已经封的足够好了。

       接下来简单聊下两个网络库特点异同:muduo是单线程处理fd,多线程处理fd上面的数据,轮询抛fd。亮点有:日志设计,定时器设计,fd耗尽的处理方式,读取数据这里。

       相较之下libevent就比较简单,没有muduo这种多线程的处理,只是单线程处理fd。其它就需要开发者去根据自身业务做定制化开发集成,github上面就有360的人根据libevent封的网络库,据说优化性能挺好,作者看过源码,并未使用,感兴趣的人可以简单看看。

       github上面c++开源代码较多且有质量的大公司就两个,一个360一个腾讯,其中腾讯的libco,各种文章数据吹的挺凶残。libco本质上就是用epoll做调度,处理一个定时器事件,一个正常的fd事件,阻塞操作就调用定时器调出去,等到时间到了再把数组里的函数运行堆栈切回来这样。腾讯开源的代码里还有个根据云风的协程api自己搞了个网络库,也可以简单看看。      

       总结这几年的工作经验,我认为的网络库应该是如下这样的:

       不使用libco,底层用epoll,边缘触发,不考虑支持win,单线程处理监听fd,2-3个(可配置)io线程处理fd上面的数据包抛到任务队列,多(可配置)线程处理任务队列,任务队列这里频繁的话,这里加锁建议加自旋锁,或者可以使用无锁编程,因为这里应该频繁有数据过来,恰好适合用CAS无锁编程。这里建议每个线程单独用一个任务队列,为使任务队列尽量均匀,可根据数据包某个字段hash到特定线程去处理最好。任务队列这里最好搞个什么内存池之类的,频繁分配内存会有性能损耗,且有内存碎片产生,这里就空间换时间,任务队列单个结构要设计的通用简单。

       定时器设计这里仿照lievent的小顶堆,epoll_wait最后一个参数做文章。

       日志库设计可以参照muduo,细节读写buf可以参照muduo来。fd不够用的处理也可以参照muduo的来。

       数据协议目前页面大多用json居多,还有一些用protobuf,再有一些就是自己搞的压缩算法封装,这里建议用protobuf或者json,使用json解析可以用腾讯的RapidJSON,据说性能挺好,使用起来跟其它json库不太一致,但仅就性能好,其它可以接受。

本人qq交流群:242598595。有啥商榷之处,可以交流探讨,常年不定时在线。

在转载此站点文章时,希望可以声明原作者 ,感谢。

你可能感兴趣的:(网络)