惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fortinet All Blogs
Attack and Defense Labs
Attack and Defense Labs
V2EX - 技术
V2EX - 技术
O
OpenAI News
S
Secure Thoughts
H
Heimdal Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Schneier on Security
Schneier on Security
H
Hacker News: Front Page
S
Security Affairs
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
P
Proofpoint News Feed
The Register - Security
The Register - Security
GbyAI
GbyAI
Cloudbric
Cloudbric
MongoDB | Blog
MongoDB | Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
K
Kaspersky official blog
Forbes - Security
Forbes - Security
Y
Y Combinator Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
Scott Helme
Scott Helme
Hacker News - Newest:
Hacker News - Newest: "LLM"
The Cloudflare Blog
Recorded Future
Recorded Future
人人都是产品经理
人人都是产品经理
Cyberwarzone
Cyberwarzone
C
CERT Recently Published Vulnerability Notes
Webroot Blog
Webroot Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LangChain Blog
T
Tor Project blog
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Hacker News: Ask HN
Hacker News: Ask HN
Blog — PlanetScale
Blog — PlanetScale
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog RSS Feed
N
News and Events Feed by Topic
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
V
V2EX
T
Tailwind CSS Blog
SecWiki News
SecWiki News
NISL@THU
NISL@THU
C
Check Point Blog

Lua

用 Lua 写 Android 应用? AutoLua 做到了 - V2EX Android 上直接用 Lua 调 Java API 写脚本——AutoLua 技术分享 - V2EX 使用 Android Lua Helper 在 VSCODE 中调试安卓 Lua 应用 - V2EX skynet 怎么给 mysql drive 增加对 caching_sha2_password 的支持 - V2EX 奇怪的小问题 - V2EX Lua 代码上的优化,相互学习一下 - V2EX openresty + lua 这个地方怎么写 - V2EX 求一份 lua 入门教程 - V2EX 有关 Lua 调用 C++ 编译动态库程序 - V2EX 飞书 + Lua 实现企业级组织架构登录认证 - V2EX 为什么游戏架构要用事件来驱动? - V2EX vscode 上写 lua 有显示注释的插件吗? - V2EX lua 为什么要使用~=当作不等于运算符? - V2EX 请问现在 lua 混淆用什么工具,求常年 lua 的老哥指点 - V2EX lua 的前景如何? - V2EX 如何构建伪视频流服务? 低延时低采样, 基于 OpenResty , HTTP, 内网... TP-Link 官方使用的是开源固件? 表达过去、现在与将来:之将来(1) - V2EX 有个问题, lua 平时能用来做做什么 - V2EX ngx_lua 遇到的一个小坑 - V2EX Lua IDE 各位 V 友,用 lua 作为开发语言用什么 IDE 可以方便代码提示以及调试呢 - V2EX Lua 怎么实现 php strstr() 函数的功能 - V2EX 使用 Sol2 来进行 Lua 绑定 - V2EX luarocks 使用上的一些小技巧 - V2EX 正在用 lua 写一个 nginx 防盗链的拓展,遇到了一个问题。 - V2EX 9k-18k 宁波 经验 3-5 年 本科及以上 全职 职位诱惑 : 年终奖 出国旅游 顶级办公设备及环境 - V2EX 关于 Lua 的标准库 - V2EX Torch - V2EX 一个在 MediaWiki 里面加入 Lua 脚本的插件 - V2EX ngx_lua_reqstatus 实时监控 Nginx 域名 qps 的 lua 拓展 - V2EX 首页搜索到 14 个 python,现在应该是 15 个了,为神马没有 lua 一席之地 - V2EX 学习 ngx_lua - V2EX 用 Lua 写 Telegram 的 Bot - V2EX Lua 资料收集整理 - V2EX 云风翻译了 Lua 5.3 的手册 - V2EX 我对 Lua coroutine 的理解,希望有人能指点下有哪些更适合的使用场景或高阶用法~ - V2EX Lua 5.3 - V2EX 为什么 Lua 本身不包含像 endswith() 之类的特别常用的字符串函数呢? - V2EX 为 Atom 写了一个 linter-luacheck,希望大家喜欢 - V2EX lua 如何最快速度入门 - V2EX 学习 Lua,请问各位有什么书推荐? - V2EX lua 很牛啊,有人在服务端用 ta 么? - V2EX LÖVE - V2EX Scripting Nginx with Lua - V2EX 关于 openssl aes-256-cbc 的一些参数 - V2EX LuaJIT 2.1 PPA - V2EX 谁会Luci的cbi模块?怎样实现重启服务? - V2EX lua有没有3des加密解密的模块? - V2EX 关于学习 Lua 有什么好书推荐么? - V2EX lua好像有种简化的语法,叫啥来着 - V2EX
core_framework - 基于 libev 的轻量级 lua 网络开发框架
CandyMi · 2019-03-27 · via Lua

—— 大道至简, 返璞归真.

前言

在发表这篇博文的前夕, 还有一些小伙伴在提问一些以下相关的问题:

  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 注册回调事件.
  1. 为当前注册的所有事件创建一个 Lua 协程保存上下文并让出当前协程执行权.
  1. 等到注册事件被触发后, 调用 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. httpdhttpc
  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 项目的目标不是竞争, 而是明白明白简单为美. 当你习惯了它, 也许你就会上瘾.


使用示例

精彩截图

部署面板

状态面板

pod 日志

希望

也许你正在使用其它开发框架, 但是这不妨碍你对 cf 的督促.

也许你正在试用它, 这不妨碍你与作者沟通你的想法.

也许你正在吐槽它的缺点,请来issue尽情吐槽.

文档与地址

项目文档

项目地址