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/

相關文章
相關標籤/搜索