七牛云存儲開源的網絡庫:CERL

y37f 9年前發布 | 37K 次閱讀 CERL 網絡工具包

CERL2.0 - Erlang Model for C++

重要聲明

開放 CERL2.0 僅僅基于供學術研究的目的。不建議你基于 CERL 開發任何商業代碼。目前來說,沒有任何人來推進 CERL 的后續改進計劃。也沒有人為如何使用 CERL 提供基本的、必要的支持。

背景

CERL 既然是2009年的產物,為何遲遲沒有開源?

實際上,在 2011 年初我們很嚴肅地討論過是否將 CERL 開源的事情。我至今仍然清楚地記得道神(李道兵)當時的建議:應該盡快開源 CERL,如果有一天 Go 流行起來了,開源 CERL 就完全沒有意義了。我當時也口頭和大年(盛大創新院院長陳大年)溝通了把 CERL 庫開源的想法,大年表示支持,并說讓我發信給他提交正式的申請。不過,我反復考慮了下我在這個事情上希望達到的目標是什么。結果我發現我并沒有找到支持我 去將 CERL 開源的動力。那時我雖然還沒有決定將開發的工具鏈切換到 Go,但是已經意識到 C++ 作為服務端開發的成本是非常昂貴的。CERL 這個網絡庫一定程度上達到了它預期的目標 —— 給 C++ 服務端開發降低負擔,但是 C++ 本身的包袱太重,以至于我并不認為我已經找到了一種服務器端編程的最佳實踐。

所以,支持我不開源 CERL 的原因非常簡單:我不想開放一個連我自己接下來都不打算去使用的東西給社區。因為我認為那是極不負責任的做法。

為何今天我重新考慮將 CERL 發布出來?

在 ECUG Con 2014 大會,我重新回顧了我整個服務端最佳實踐的歷程,這一次我沒有像 2010 年杭州的 ECUG Con 大會那樣含糊其詞,而是非常鮮明地探討了 Erlang 編程范式的自相矛盾之處 ( http://blog.qiniu.com/archives/1059 )。盡管我自認為這只是技術探討,并非是對 Erlang 語言并沒有惡意攻擊(我至今仍然極度推崇 http://open.qiniudn.com/[Joe-Armstrong]Making-reliable-distributed-systems-in-the-presence-of-software-errors.pdf ,認為那是對我個人了解分布式編程理論的啟蒙之作),這個演講確實讓 Erlang 社區同學們大為受傷。這其中又以某位號稱 Erlang 大拿的專家為最:

image

我最初知道這件事情是道神給我發了一個信息,說知乎上有人對我那篇演講開罵,我回復說:你很難討好所有人,所以這事不必理會。但真到我看到罵的內容 時,還是讓我大為震怒。上面貼的是經過此人多次修飾后的內容,借自嘲自己寫寫了不少狗屎代碼來試圖讓內容顯得理性一些,最初的帖子則純屬謾罵。

讓我震怒的原因有兩點,一個這樣的謾罵來自于曾經以為的朋友。一個是說 CERL 是狗屎,罵的并不只是我自己,而是整個盛大云存儲團隊。因為我個人原因,導致整個團隊被罵,這一點讓我非常難堪。

我重新考慮關于 CERL 開源的決定。就我個人而言,我自認為 CERL 代表了我自己在 C++ 領域的巔峰。也是我告別 C++ 的作品。但是整個 CERL 庫的開發小組而言,這也許只是他們的某個里程碑。我因為個人非常自私不想承擔責任的原因,將 CERL 庫雪藏,也許并不見得是非常正確的決定。

于是我重新微信聯系到了大年,探討 CERL 庫開源的事項。大年說,沒問題,如果你需要,你可以找我簽個合同。我說年總一諾千金,這事只是個小事,CERL 庫現在事實上也處于沒有客戶的狀態(何剛接管盛大云存儲后,用 Java 重寫了整個存儲核心),沒必要大費周章。

于是,CERL 庫今天終于重見天日。

為了保留盡可能多的研究價值,我特意連里面的 meeting minutes(會議紀要)也沒有刪除,方便大家從中看到 CERL 的演化歷史。

最后,我也憑借記憶整理了 CERL 庫的貢獻者名單:

  • 許式偉
  • 于曦鶴
  • 莫華楓
  • 馬飛濤
  • 宋海濤
  • 段雪濤
  • 李杰
  • 王歡
  • 金克
  • 李道兵
  • 郭理靖

關于 CERL 庫的性能

沒有最新的對比數據,2009 年由莫華楓提供的測試數據大致是:

  • 在沒有設定超時的情況下,CERL 的 performance 大體和 boost asio 相同。
  • 在支持 io timeout 的情況下,CERL 的 performance 遠好于 boost asio。究其原因是因為 CERL 的定時器做了較大程度的優化,而 boost asio 的定時器寫得只是中規中矩。

CERL 庫的基本結構

整個 REPO 包含 5 個子項目,從依賴關系來說,依次是:

  • memory: Boost Memory 庫。這個庫因為曾經提交到 Boost Sandbox 中,所以放在 boost 目錄下。如果我還繼續用 C++,也許會嘗試讓它進 Boost 庫。這個庫早就開源,最初放在 google code 上,其最新地址在 https://github.com/xushiwei/memory
  • stdext: C++ 擴展庫。內容比較雜,整體可以認為是我在金山時期積累的 KFC 庫的重新梳理版。這個庫早就開源,最初放在 google code 上,其最新地址在 https://github.com/xushiwei/stdext
  • tpl: 文本處理庫。這個是因為 CERL 里面定義了一門叫 SDL(Server Description Language),需要實現一個編譯器而依賴。這個庫早就開源,最初放在 google code 上,其最新地址在 https://github.com/xushiwei/tpl
  • async: CERL 庫的核心。雖然名字叫 async,但是它的編程模型是基于 fiber(纖程)寫同步的程序。整個編程理念反對任何地方出現異步代碼。這個庫經歷了多次演化,從最初的純 Erlang Model,到試圖引入預編譯器將同步代碼翻譯成異步代碼,到最后決定基于 fiber(纖程)直接寫同步代碼(詳細見 meeting minutes),從而最終確定了整個編程哲學。
  • venus: 基于 async 庫寫的一個 RPC 框架。推薦寫服務器的標準方式是先寫一個 SDL,然后基于這個 SDL 用 venusc 編譯出 Server 端框架和 Client 端的 SDK。這樣實現者只需要在 Server 端框架里面填寫業務代碼,Client 端直接基于生成的 SDK 去調用服務器的功能。關于 SDL 語言的細節,我曾經在 CSDN 博客做過詳細介紹:http://blog.csdn.net/xushiweizh/article/details/4444942

更多細節,后面得空再補。也歡迎小伙伴們提 pull request 進行完善。

最后再次強調:

  • 非常不推薦基于 CERL 庫來寫商業代碼。但是學習 CERL 庫(特別是 async 這個子庫)也許非常有助于你理解 Golang 語言的背后機理。而了解 CERL 的整個歷程,也可能有助于你理解為何七牛選擇了 Golang。

CERL 這個詞的來源是因為他被定為為:Erlang Model for C++。目的是在C++中獲得Erlang的好處(部分)。不過,實際上CERL被實現為與語言無關的。基于CERL,你可以用PHP、Python之類的語言來寫服務器或客戶端。
CERL 基于Erlang的分布式模型。實現了Erlang做最重要的幾個概念:Node, Process, Mail (Message)。他也支持速錯(Fail fast)及GenServer編程框架。當然,也有它沒有做到的,如:
CERL 不支持輕量級的進程。盡管CERL的Process模型和Erlang一致,但是他并不輕量,事實上CERL的進程就是操作系統中的Thread。剛開始我準備用協程,不過后來被證明這是不必要的,所以CERL永遠都不考慮協程這東西。CERL 不支持熱部署。當然,這是指他沒有提供機制支持,而不是指你沒法做到。
CERL對外表現為一個動態庫(cerl.dll) + 一個編譯器(sdlc)。邏輯上CERL分為兩層,底層稱為CERL Core,上層為GenServer框架。
CERL Core –表現為動態庫cerl.dll。主要實現Erlang的分布式模型,及其他輔助基礎設施。GenServer框架。它主要定義了服務器接口描述語言: Server Description Language(SDL),并提供相應的編譯器 sdlc 以生成:客戶端如何調用該服務器的Proxy代碼。服務器端Stub代碼。服務器Impl文件的框架代碼。

項目主頁:http://www.baiduhome.net/lib/view/home/1426390994917

 本文由用戶 y37f 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!