libevent和libev高性能网络开发组件

在构建大型网络服务时,服务器同时接收数百、数千甚至数万个链接请求,服务端就须要对这些请求做出及时响应,在本文中,咱们要讨论在 UNIX应用程序中使用和部署这些解决方案所用的基本结构和方法。libevent和libev是一种开源的高性能网络事件处理库。web

首先简要回顾一下传统网络链接的解决方案:后端

处理多个链接有许多不一样的传统方法,可是在处理大量链接时它们每每会产生问题,由于它们使用的内存或 CPU 太多,或者达到了某个操做系统限制。数组

使用的主要方法以下:服务器

  • 循环:早期系统使用简单的循环选择解决方案,即循环遍历打开的网络链接的列表,判断是否有要读取的数据。这种方法既缓慢(尤为是随着链接数量增长愈来愈慢),又低效(由于在处理当前链接时其余链接可能正在发送请求并等待响应)。在系统循环遍历每一个链接时,其余链接不得不等待。若是有 100 个链接,其中只有一个有数据,那么仍然必须处理其余 99 个链接,才能轮到真正须要处理的链接。
  • EPOLL:这是对循环方法的改进,它用一个结构保存要监视的每一个链接的数组,当在网络套接字上发现数据时,经过回调机制调用处理函数。poll 的问题是这个结构会很是大,在列表中添加新的网络链接时,修改结构会增长负载并影响性能.
  • select:函数调用使用一个静态结构,它事先被硬编码为至关小的数量(1024 个链接),所以不适用于很是大的部署。

上面的全部解决方案都用简单的循环等待并处理请求,而后把请求分派给另外一个函数以实际的网络交互。关键在于循环和网络请求须要大量管理代码,这样才能监听、更新和控制不一样的链接和接口。网络

处理许多链接的另外一种方法是。利用系统内核已有的多线程来监听和处理链接,为每一个链接启动一个新线程。可是会在RAM和CPU方面增长至关大的开销,由于每一个线程都须要本身的执行空间。另外,若是每一个线程都忙于处理网络链接,线程之间的上线问切换回很频繁。最后许多内核并不适于处理大量的活跃线程。多线程

  • libevent方法

    libevent 库实际上没有更换 select()poll() 或其余机制的基础。而是使用对于每一个平台最高效的高性能解决方案在实现外加上一个包装器。函数

    为了实际处理每一个请求,libevent 库提供一种事件机制,它做为底层网络后端的包装器。事件系统让为链接添加处理函数变得很是简便,同时下降了底层 I/O 复杂性。这是 libevent 系统的核心。性能

    libevent 库的其余组件提供其余功能,包括缓冲的事件系统(用于缓冲发送到客户端/从客户端接收的数据)以及 HTTP、DNS 和 RPC 系统的核心实现。测试

    建立 libevent 服务器的基本方法是,注册当发生某一操做(好比接受来自客户端的链接)时应该执行的函数,而后调用主事件循环 event_dispatch()。执行过程的控制如今由 libevent 系统处理。注册事件和将调用的函数以后,事件系统开始自治;在应用程序运行时,能够在事件队列中添加(注册)或删除(取消注册)事件。事件注册很是方便,能够经过它添加新事件以处理新打开的链接,从而构建灵活的网络处理系统。编码

  • libev库

    与 libevent 同样,libev 系统也是基于事件循环的系统,它在 poll()select() 等机制的本机实现的基础上提供基于事件的循环。到我撰写本文时,libev 实现的开销更低,可以实现更好的基准测试结果。libev API 比较原始,没有 HTTP 包装器,可是 libev 支持在实现中内置更多事件类型。例如,一种 evstat 实现能够监视多个文件的属性变更。

    可是,libevent 和 libev 的基本过程是相同的。建立所需的网络监听套接字,注册在执行期间要调用的事件,而后启动主事件循环,让 libev 处理过程的其他部分。

结束语

libevent 和 libev 都提供灵活且强大的环境,支持为处理服务器端或客户端请求实现高性能网络(和其余 I/O)接口。目标是以高效(CPU/RAM 使用量低)的方式支持数千甚至数万个链接。在本文中,您看到了一些示例,包括 libevent 中内置的 HTTP 服务,可使用这些技术支持基于 IBM Cloud、EC2 或 AJAX 的 web 应用程序。

 

参考:https://www.ibm.com/developerworks/cn/aix/library/au-libev/

相关文章
相关标签/搜索