溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

core_framework —— 基于libev的輕量級lua網絡開發框架

發布時間:2020-07-07 17:59:10 來源:網絡 閱讀:254 作者:CandyMi 欄目:軟件技術

大道至簡, 返璞歸真.

前言

在發表這篇博文的前夕, 還有一些小伙伴在提問一些以下相關的問題:

  1. 性能怎么樣?

  2. 是否容易上手?

  3. 開發目標在哪?

  4. 如何反饋問題?

  5. 對比行業內的lua開源項目有何優勢?

等等, 以上問題會在本文中一一介紹.


CF的起因

首先來聊聊情懷這個東西! 相信每一個行業內的從業者都或多或少有過一個夢, 這個夢叫做: "我到時候要開發一個XXX"!其實作者當初也是一樣.

每當半夜(凌晨)在加班、看文檔、調試的時候, 總會搜索到一些幾年前或十幾年前的框架或入門demo。例如: tinyhttp, 鏈接的源碼是一些同學fork的鏡像站。

每次看到這些內容或多或少都會激起心中那一絲絲快熄滅的熱情, 也許這就是最后對技術的渴望?

就是在動手創建項目之前還反復問過自己是否要做? 能堅持下去么?也許被噴都是一種奢望?

在心里一一回答了這些問題后, 在2018年末創建了本項目.

說句實話! 一個網絡開發框架最難的不是實現某個功能, 而是從零開始一步一步添磚加瓦的造輪子!

作為一個網絡開發框架, 最重要的兩個功能肯定是需要的! 定時器庫、事件驅動庫. 如何抉擇?選項有2個: libev / libuv .

libev 成熟穩定、輕量級、unix like支持、容易嵌入;

libuv 比libev更加優秀,增加了許多功能(線程池、信號、同步、鎖等等),封裝更加完善, 并且增加了windows支持;

從cf框架開發之初選型來看, libuv絕對是目前最優解. 但是作者偏偏選擇了libev. 也從此開始, 艱辛的底層開發之路就此展開.

首先, 作者不讓使用者C/C++進行實際業務開發! 這樣做會讓使用者有較高的開發成本與學習成本, 而選擇一門較好的腳本語言就顯得尤為重要.

作者對Lua還算是稍微熟悉一點, 所以就選了Lua作為業務腳本語言。至于Lua語言的優勢這里就不說了, 網上大把文章夸它的.

現在既然腳本語言已經選定, 那么就開始寫代碼吧!Let's Lua.


CF的編寫之路

1. 網絡層

首先, 我們來看一段C封裝給Lua調用的API代碼:

LUAMOD_API int
luaopen_tcp(lua_State *L){
    luaL_checkversion(L);
    /* 添加SSL支持 */
    SSL_library_init();
    SSL_load_error_strings();
    // CRYPTO_set_mem_functions(xmalloc, xrealloc, xfree);
    // OpenSSL_add_ssl_algorithms();
    /* 添加SSL支持 */
    luaL_newmetatable(L, "__TCP__");
    lua_pushstring (L, "__index");
    lua_pushvalue(L, -2);
    lua_rawset(L, -3);
    lua_pushliteral(L, "__mode");
    lua_pushliteral(L, "kv");
    lua_rawset(L, -3);
    luaL_Reg tcp_libs[] = {
        {"read", tcp_read},
        {"write", tcp_write},
        {"ssl_read", tcp_sslread},
        {"ssl_write", tcp_sslwrite},
        {"stop", tcp_stop},
        {"start", tcp_start},
        {"close", tcp_close},
        {"listen", tcp_listen},
        {"connect", tcp_connect},
        {"ssl_connect", tcp_sslconnect},
        {"new", tcp_new},
        {"new_ssl", ssl_new},
        {"free_ssl", ssl_free},
        {"new_server_fd", new_server_fd},
        {"new_client_fd", new_client_fd},
        {NULL, NULL}
    };
    luaL_setfuncs(L, tcp_libs, 0);
    luaL_newlib(L, tcp_libs);
    return 1;
}

以上是TCP實現的C代碼的片段, 有興趣閱讀源碼的小伙伴請點擊這里;

眾所周知Lua沒有原生的Socket. 那么就需要框架編寫者自己抽象底層邏輯重新實現一套API.

簡單的封裝Lua C庫誰都會, 而且也算不上是什么難事. 但是我們的目的是將底層同步阻塞Socket hook為非阻塞, 這時候難點就來了!

大家都知道libev是基于react模型的事件驅動網絡庫, 所有注冊事件后的業務邏輯都是以回調的形式觸發. 那不就變成node-lua代碼了嗎?(笑)

這時候, 作者想了個點子來解決這個問題! 執行流程如下:

  1. 每次需要做一些同步操作的時候, 就調用C API注冊回調事件.

  2. 為當前注冊的所有事件創建一個Lua協程保存上下文并讓出當前協程執行權.

  3. 等到注冊事件被觸發后, 調用C API恢復協程繼續執行.

簡單來說就是將C層次的異步回調邏輯封裝為Lua層的同步非阻塞, 保證不因為IO問題阻塞線程.

下面提供一段socket同步非阻塞的偽代碼, 經供參考:

function TCP:recv(bytes)
    local current_co = co_self()
    self.read_co = read_ev(function()
    -- do action
    -- stop timer_ev
    -- wakeup(current_co) 恢復執行權
    end)
   self.timer_co =  self.timer_ev(function()
    -- do action
    -- stop read_ev
    -- wakeup(current_co) 恢復執行權
    end)
    tcp_start(io, EV_READ, self.read_co)
    timer_start(timer, 3秒超時, self.timer_co)
    return co_yield() -- 讓出執行權
end

一個Lua版的Socket EV_READ偽代碼大致的處理流程如上, 想看實際處理邏輯請看這里。

同理, Socket write/connect/listen等等API直接照抄就行(UDP也大同小異). (其實這里有個小插曲就是SSL SOCKET的坑, 但是由于篇幅問題就不說了.)

細心的小伙伴可能發現代碼同時注冊了Socket與Timer事件, Socket非阻塞操作不能解決read與connect超時的問題. 所以cf框架干脆就封裝徹底一點.

至此, Socket算是已經算是基本hook與封裝完成了. 接下來就可以開始寫應用層協議了.

2. 應用層協議

現在Socket終于能正常使用了, 那么面臨的新問題就又來了。

libev沒有自帶異步dns

dns都還需要使用者自己封裝, 這個坑真是填的無比難受! 好在網絡上有前輩實現了Lua版的異步dns, 作者稍微看明白之后就借用了過來封裝內部使用.

這樣cf也算是有了深度定制的異步dns庫了吧!(雖然并不完善, 但是足夠使用)

一個網絡庫是否流行, 基本上就得看生態. 那么協議層的輪子又得造起來:

  1. httpd與httpc
  2. mail
  3. mysql
  4. redis
  5. mqtt
  6. websocket

其中一些協議為各位前輩那邊借過來適配后定制的, 簡單的協議則是直接花1-2小時直接手寫出來的。

3. 封裝與易用性

為了不讓API那么封閉與提升cf的可用性, 作者決定將mysql與redis進行初步封裝.

封裝包括大家常用的功能, 連接池、面向對象操作、無需手動管理session生命周期等等. 簡化編程思想包袱來提升開發效率.

至于內部Socket更是讓框架來解決釋放問題確保文件描述數量限制的情況下也是可以正常使用. (其實是不喜歡依賴gc被動close fd與free內存)


CF是啥?

如果你耐心看完了第一部分介紹, 那么你就應該對cf有了一個大概的了解.

cf全稱為: CoreFramework, 是一個基于libev的Lua網絡開發框架. 在其內部實現了多種網絡協議與第三方庫用來幫助使用者進行項目原型的快速開發.

cf 在httpd使用上尊崇前、后端分離的解決方案, 僅實現了基本的view路由并且不支持rest風格的API路由. 雖然這樣可能會引來宇多人的詬病.

cf 的httpd內嵌websocket支持, 方便使用者在復用端口的同時也可以享受長連接編寫的樂趣.

更多的介紹, 請大家項目地址的Wiki


CF能做什么?

  • 基于容器技術的微服務場景(swarm/kubernetes); —— 推薦

  • 游戲服務器的前端代理層; —— 推薦

  • 內存/CPU資源較為緊缺的云服務器; —— 推薦

  • 對性能要求較高的無狀態集群; —— 推薦

  • 海量長連接(websocket)Agent集群; —— 推薦

CF使用到的技術棧?

傳輸層: TCP/UDP

會話層: SSL Client支持

協議層: dns/webocket/http/mqtt/redis/mysql/smtp

工具庫: Timer/TASK

第三方庫: Libev、openssl/libressl、lua-5.3、jemalloc/tcmalloc(可選)


CF如何安裝?

cf 目前支持絕大部分Unix like操作系統, 作者是在Mac上進行開發, 所以Mac支持是必須的.

cf測試的Linux為Centos, 所以基本上基于Linux內核的操作系統編譯后的運行也沒什么問題(export 增加/usr/local/lib)

同時,作者還貼心的為大家做了一個簡單Dockerfile. 文件在項目根目錄下, 大家下載直接使用即可。

當然, 如果你不想制作Dockerfile,也可以使用Docker命令直接拉去作者制作好放在docker hub的鏡像. candymi/cfweb

使用詳情與使用方法請參考Docker安裝和編譯安裝


CF 如何運行呢?

測試運行

bash#: ./cfadmin

后臺運行

bash#: ./cfadmin

退出

killall cfadmin

ctrl + c


文檔在哪?

作者為大家貼心的寫了一篇詳細到不能再詳細的文檔, 以此來獲取大家的點贊與關注.

作者還為喜歡閱讀源碼的同學準備了充足的中文注釋與英文注釋, 結合起來方便大家快速了解CF工作方式(中/英注釋結合易于理解一些專屬詞匯).


回答之前的問題:

Q. 性能怎么樣?

A. 性能還不錯, 但是具體數值請自行測試.

Q. 是否容易上手?

A. 學習lua 一小時入門 -> cf 一小時入門

Q. 開這個項目的初衷是什么?

A. 其實在前面已經回答過了.

Q. 開發目標在哪?

A. Wiki 里有TODO項

Q. 如何反饋問題?

A. Wiki 里有Q & A項

Q. 對比行業內的lua開源項目有何優勢?

A. CF對比其它lua開發項目更深入改變用戶使用習慣! 簡化框架上手難度, 將框架都黑盒子透明化. 無需學習復雜的設計模式與理念.

Q. CF的開發理念是什么?

A. CF項目的目標不是競爭, 而是明白明白簡單為美. 當你習慣了它, 也許你就會上癮.


使用示例

  • 容器部署

    • Dockerfile快速構建開發環境

    • cf k8s中的應用示例
  • cf web的初始化與使用

  • cf web Websocket應用指南

  • cf web 中間件開發指南

精彩截圖

core_framework —— 基于libev的輕量級lua網絡開發框架

core_framework —— 基于libev的輕量級lua網絡開發框架

core_framework —— 基于libev的輕量級lua網絡開發框架

希望

也許你正在使用其它開發框架, 但是這不妨礙你對cf的督促.

也許你正在試用它, 這不妨礙你與作者溝通你的想法.

也許你正在吐槽它的缺點,請來issue盡情吐槽.

文檔與地址

項目文檔

項目地址

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女