C++ 高性能服务器 网络库介绍

1.大型高并发,高性能

2.异步IO

3.均衡负载

multi-reactor服务器模型的C++封装类(libevent+多线程实现)

libevent:这是在网上找的资料,libevent并不是线程安全,但不代表其不支持多线程。memcache的网络部分使用libevent,有一个经典的图描述了其多线程实现: 

C++ 高性能服务器 网络库介绍

 

高性能、高并发TCP服务器(多线程调用libevent)

https://blog.csdn.net/I_am_JoJo/article/details/7587838

 

各种网络库比较 asio libevent

 

libevent

libev

libuv

工具库和框架之间的区别,asio是被设计成一套工具库而不是框架。

什么是框架? 框架就是一套固定了编程结构的库,任何用户使用它,必须按照框架库的结构设计自己的应用,比如MFC中的OnOK, OnXXX之类,又或者ACE中的ACE_Handler::handle_xxx_yyy之类,用户通过在这些派生类的虚函数中实现自己需要的处理。  

什么是工具库? 而工具库就是一套api,而不是框架,用户使用它,无需从指定的地方去填写代码。程序的框架由用户自己决定。类似的库有C++中的STL,C中的标准库,它们从来不提供编程框架,而只提供工具函数,让用户通过这些工具函数,正确的组织自己的程序结构。 

框架的限制非常多,不够灵活

 

ACE 过于复杂,甚至比它试图封装的对象更复杂

libevent 就如名字所言,是一个异步事件框架。

libevent把简单问题简单化,让异步网络编程反朴归真,应该来说,本是一个好库。

然而 libevent 因为设计缺陷,例如使用全局变量,定时器无法处理时间跳变,诸如此类的设计缺陷导致了 libev 的出现。
libev 就是为了克服libevent的缺陷而诞生的。然而,libev 就一定好了吗?

 

ibev 带着对 libevent 的怨气出世了。

 

编写异步程序, 最需要的2个抽象能力, 其一为协程,其二是函数对象,包括匿名函数对象, 也就是lambda。
C统统没有。函数对象是实现闭包比不可少的,如果没有函数对象, 就只能通过携带 void* 指针的形式迂回完整,繁琐不说,还特别容易出错。

尽管C 有那么多缺点,然而 libev 还未来得及被C的缺点拖累,因为他不支持 IOCP. 于是 libuv 就出来给 libev 擦屁股了。 

libuv 可以说是 C 语言的异步库所能达到的最高高度了。完完全全的触碰到了C语言的自身瓶颈,好在 libuv 只是 nodejs 的底层库,上层软件转移到 javascript 语言而逃避了 C 的禁锢。

 

ASIO 腾空出世

在地球最大的岛上,另一位少年开始拜读 ACE 的大作。那时候,没有 libuv 没有 libev 更没有 libevent . 有的只是 ACE.

少年在一次开发者大会的演讲上,再次透露,网络库不宜做成框架,而是要像系统的API那样,作为一个乐高积木。ACE 做成了一个框架,同样不妥。

asio采用proactor模式,而windows下的IOCP本身就是这个模式的体现

在高性能服务器并发模型设计中,Reactor和Proactor是两个经常用到的设计模式,前者用于同步IO,后者用于异步IO,前者在IO操作 就绪的情况下通知用户,用户再采取实际的IO操作,后者是在IO操作完成后通知用户。

IOCP的设计就是Proactor 模式的完美体现,而epoll则很容易实现Reactor模式,asio设计为跨平台,并且在linux下采用epoll,我的印象中linux对异步 IO的支持没有windows那么完善(看看IOCP和epoll模型的区别就知道),那么asio是怎么用epoll机制实现proactor模式的 呢,刚开始想的是应该在应用层做了一层封装,就是asio内部应该有某个循环调用epoll_wait,当有IO事件就绪时帮用户做一些操作(比如把数据 拷贝到我们提交的缓冲区),然后在操作完成的时候调用我们的handler(后来看代码基本是这样).OK,不说废话了.

 

本质上来讲libevent应该是同步的,因为如果看到底层封装的select和epoll就会发现,里面仍然是个while循环,在不停的询问,是否准备就绪,
而异步同步IO的主要区别就是,应用发起一个 IO 操作以后,不等待内核 IO 操作的完成,等内核完成 IO 操作以后会通知应用程序,这其实就是同步和异步最关键的区别,同步必须等待或者主动的去询问 IO 是否完成,显然select和epoll是同步的。
另外本身Reactor模式就是同步的模式不是吗?



如果你理解底层的select或者epoll。你会发现它其实是同步的。有一个while循环,等待事件触发条件。满足条件则调用相应的callback函数。因此本质上还是同步的。不过长了一个异步的脸

libevent本身是一个Reactor,是同步的。但libevent的bufferevent是用Reactor实现了一个Proactor,所以libevent又是异步的

 

TCP ping-pong 测试

 

go 收发20W QPS  单线程/多线程 

boost::asio 收发 9W7  QPS 单线程 / 多线程

ae(Redis网络库) 收发7W5 QPS   单线程

libuv 收发 6W9 QPS   单线程

 

libevent、libev、libuv、IOCP、asio、muduo优劣分析、QT下编译libevent静态库

https://blog.csdn.net/tjm1017/article/details/88219576

https://blog.csdn.net/tjm1017/article/details/88219576

libev与libuv的区别

https://www.cnblogs.com/charlesblc/p/6341280.html

 

https://blog.csdn.net/sinat_22991367/article/details/102996964

linux多线程网络库-muduo库学习

 

跨平台多线程服务端编程:使用 asio C++ 网络库

 

https://blog.csdn.net/libaineu2004/article/details/43670931

 

Boost.Asio,libevent和ACE之间关于Socket编程的比较(★firecat推荐★)

https://blog.csdn.net/libaineu2004/article/details/43670931